features.c 95 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165
  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. // TODO
  22. // so far I've got FE_WINDOWS (mode 4) outputting time frq amp TRIPLES .. converted to samps frq color
  23. // AND these ARE SNACK displayed in Features window.
  24. // calling SNACK with evv(SN_FEATURES_PEAKS)
  25. // and displaying the SPECTRUM and the peak data on TOP OF THE SPECTRAL DISPLAY, to see if it is credible !!!!
  26. //
  27. // cmdline:: DEFAULT
  28. // lof hif mindist-btwwn peaks scan-wsize no-of-pks no-of-windows at-time sort-anal-files-to-frq-order
  29. // features get 4 infile.ana 350 8000 43 500 4 14 .5 -s
  30. //
  31. // NOTICEABLE THAT ISOLATED POINTS COULD BE DELETED
  32. // isolated means no point within next 4(3?) windows is within 500/2 = 250 Hz of the point
  33. //
  34. //
  35. // Create Sloom display for modes 6,5,4
  36. // Tesat on vocal data!!
  37. // If outputs seem reasonable, do code for modes 1,2,3
  38. /*
  39. * mode 1: EDIT TIMES OUTPUT: times to edit out longest OR loudest example of each feature.
  40. * mode 2: EDIT TIMES OUTPUT: times to edit out every example of J marks
  41. * mode 3: ENVEL OUTPUT: times to envelope everything except the marked items.
  42. * mode 4: TEST MODE: creates data display of N windows at time K
  43. * mode 5: TEST OUTPUT: outputs peakfrqs and spectral amplitudes to put on display and compare.
  44. * mode 6: TEST MODE: creates data display of average peaks over spectrum from time A to time B
  45. */
  46. #include <stdio.h>
  47. #include <stdlib.h>
  48. #include <structures.h>
  49. #include <tkglobals.h>
  50. #include <pnames.h>
  51. #include <filetype.h>
  52. #include <processno.h>
  53. #include <modeno.h>
  54. #include <logic.h>
  55. #include <globcon.h>
  56. #include <cdpmain.h>
  57. #include <math.h>
  58. #include <mixxcon.h>
  59. #include <osbind.h>
  60. #include <standalone.h>
  61. #include <speccon.h>
  62. #include <ctype.h>
  63. #include <sfsys.h>
  64. #include <string.h>
  65. #include <srates.h>
  66. #if defined unix || defined __GNUC__
  67. #define round(x) lround((x))
  68. #endif
  69. #ifndef HUGE
  70. #define HUGE 3.40282347e+38F
  71. #endif
  72. #define EQUALFRQ 1
  73. char errstr[2400];
  74. int anal_infiles = 1;
  75. int sloom = 0;
  76. int sloombatch = 0;
  77. const char* cdp_version = "7.1.0";
  78. #define MIDIMINFRQ (8.175799)
  79. #define MIDIMAXFRQ (12543.853951)
  80. #define MIDDLE_C_FRQ (261.625565)
  81. #define MIN_FE_DUR (10) /* minimum feature length (mS) */
  82. #define DFLT_MAX_FE_LEN (600) /* max length of a feature (mS) */
  83. #define FE_MAX_WIN (14) /* resolution on a 900 pixel wide display with 60 semitones */
  84. #define DFLT_PK_ERROR (2.0) /* semitones */
  85. #define DFLT_PK_STEP (1.0) /* min step between peaks (semitones) */
  86. #define MAJOR_3RD (4.0) /* semitones */
  87. #define FE_MAX_PKCNT (6)
  88. #define DFLT_PEAKS_CNT (3) /* no of formant peaks to search for */
  89. #define FE_CNT_MAX (1000) /* max no of different features to search for */
  90. #define FE_CNT_TYPICAL (40) /* typical no of different features to search for */
  91. #define FE_TAILMAX (1000)
  92. #define FE_TAILDUR MIN_FE_DUR
  93. #define FE_SPLICEMAX (50)
  94. #define FE_SPLICELEN (5)
  95. #define FE_MINWINDOW (5)
  96. #define DFLT_MAX_AVWIN_SIZE (1000.0)
  97. #define FE_WINSIZ_DFLT (500.0)
  98. #define FE_LOFRQ (0)
  99. #define FE_HIFRQ (1)
  100. #define FE_STEP (2)
  101. #define FE_WINSIZE (3)
  102. #define FE_PKCNT (4)
  103. #define FE_WINCNT (5)
  104. #define FE_WINTIME (6)
  105. #define FE_START (5)
  106. #define FE_END (6)
  107. #define FE_MIN (5)
  108. #define FE_MAX (6)
  109. #define FE_ERROR (7)
  110. #define FE_FECNT (8)
  111. #define FE_TAIL (9)
  112. #define FE_SPLICE (10)
  113. /* modes */
  114. #define FE_BEST (0)
  115. #define FE_EVERY (1)
  116. #define FE_ENVEL (2)
  117. #define FE_WINDOWS (3)
  118. #define FE_AVERAGE (4)
  119. #define FE_CHECK (5)
  120. #define FE_SORTBUF 0
  121. #define FE_LONGEST 0
  122. #define MIN_DB -96.0
  123. /* frequencies should lie in specific channels in the PVOC data */
  124. /* in case this is not true, look in channels a little above and a little below the channels in which frq expected to be found */
  125. /* The 'little' is defined in semitones ..... or windows if EQUALFRQ defined */
  126. #define FRQ_SRCH_ERRORBND (4)
  127. /* CDP LIBRARY FUNCTIONS TRANSFERRED HERE */
  128. static int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist);
  129. static int set_vflgs(aplptr ap,char *optflags,int optcnt,char *optlist,
  130. char *varflags,int vflagcnt, int vparamcnt,char *varlist);
  131. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  132. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  133. static int mark_parameter_types(dataptr dz,aplptr ap);
  134. static int establish_application(dataptr dz);
  135. static int application_init(dataptr dz);
  136. static int initialise_vflags(dataptr dz);
  137. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  138. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  139. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  140. static int assign_file_data_storage(int infilecnt,dataptr dz);
  141. /* CDP LIB FUNCTION MODIFIED TO AVOID CALLING setup_particular_application() */
  142. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  143. /* SIMPLIFICATION OF LIB FUNC TO APPLY TO JUST THIS FUNCTION */
  144. static int parse_infile_and_check_type(char **cmdline,dataptr dz);
  145. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,int is_launched,dataptr dz);
  146. static int setup_the_application(dataptr dz);
  147. static int setup_the_param_ranges_and_defaults(dataptr dz);
  148. static int check_the_param_validity_and_consistency(dataptr dz);
  149. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  150. static int get_the_mode_no(char *str, dataptr dz);
  151. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  152. /* BYPASS LIBRARY GLOBAL FUNCTION TO GO DIRECTLY TO SPECIFIC APPLIC FUNCTIONS */
  153. static int features_scan(dataptr dz);
  154. static double semit_to_ratio(double val);
  155. static int peaks_in_window(double botfrq,double intv_to_bot_of_srch,double intv_to_top_of_srch,double intv_to_centre_of_window,double intv_to_top_of_window,
  156. double intv_to_next_window,int *lookformax,double *lastmaxamp,int *lastmaxampchan,double *lastmaxampchanfrq,
  157. double *lastminamp,int *lastminampchan,double *lastminampchanfrq,int *win_peakchan,float *buf,dataptr dz);
  158. static int locate_pitch_centre_of_each_peak(int peakandtrofcnt,int *win_peakchan,float *win_peakamp,float *win_peakfrq,double footfrq,
  159. double intv_errorbnd,double intv_to_top_of_window,double intv_to_centre_of_window,double intv_to_next_window,
  160. float *buf,dataptr dz);
  161. static void frqsort_buf(float *buf,dataptr dz);
  162. //static float amp_to_db(double amp, double silence);
  163. //static void tellme(char *str);
  164. /**************************************** MAIN *********************************************/
  165. int main(int argc,char *argv[])
  166. {
  167. int exit_status;
  168. dataptr dz = NULL;
  169. char **cmdline;
  170. int cmdlinecnt;
  171. //aplptr ap;
  172. int is_launched = FALSE;
  173. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  174. fprintf(stdout,"%s\n",cdp_version);
  175. fflush(stdout);
  176. return 0;
  177. }
  178. /* CHECK FOR SOUNDLOOM */
  179. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  180. sloom = 0;
  181. sloombatch = 1;
  182. }
  183. if(sflinit("cdp")){
  184. sfperror("cdp: initialisation\n");
  185. return(FAILED);
  186. }
  187. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  188. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  189. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  190. return(FAILED);
  191. }
  192. if(!sloom) {
  193. if(argc == 1) {
  194. usage1();
  195. return(FAILED);
  196. } else if(argc == 2) {
  197. usage2(argv[1]);
  198. return(FAILED);
  199. }
  200. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  201. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  202. return(FAILED);
  203. }
  204. cmdline = argv;
  205. cmdlinecnt = argc;
  206. if((get_the_process_no(argv[0],dz))<0)
  207. return(FAILED);
  208. cmdline++;
  209. cmdlinecnt--;
  210. dz->maxmode = 6;
  211. if(cmdlinecnt <= 0) {
  212. sprintf(errstr,"Too few commandline parameters.\n");
  213. return(FAILED);
  214. }
  215. if((get_the_mode_no(cmdline[0],dz))<0)
  216. return(FAILED);
  217. cmdline++;
  218. cmdlinecnt--;
  219. if((exit_status = setup_the_application(dz))<0) {
  220. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  221. return(FAILED);
  222. }
  223. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  224. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  225. return(FAILED);
  226. }
  227. switch(dz->mode) {
  228. case(FE_CHECK):
  229. if(cmdlinecnt < 7) {
  230. fprintf(stderr,"Too few commandline parameters.\n");
  231. return(FAILED);
  232. } else if(cmdlinecnt > 8) {
  233. fprintf(stderr,"Too many commandline parameters.\n");
  234. return(FAILED);
  235. }
  236. break;
  237. case(FE_WINDOWS):
  238. case(FE_AVERAGE):
  239. if(cmdlinecnt < 8) {
  240. fprintf(stderr,"Too few commandline parameters.\n");
  241. return(FAILED);
  242. } else if(cmdlinecnt > 9) {
  243. fprintf(stderr,"Too many commandline parameters.\n");
  244. return(FAILED);
  245. }
  246. break;
  247. case(FE_BEST):
  248. if(cmdlinecnt < 13) {
  249. fprintf(stderr,"Too few commandline parameters.\n");
  250. return(FAILED);
  251. } else if(cmdlinecnt > 15) {
  252. fprintf(stderr,"Too many commandline parameters.\n");
  253. return(FAILED);
  254. }
  255. break;
  256. case(FE_EVERY):
  257. case(FE_ENVEL):
  258. if(cmdlinecnt < 13) {
  259. fprintf(stderr,"Too few commandline parameters.\n");
  260. return(FAILED);
  261. } else if(cmdlinecnt > 14) {
  262. fprintf(stderr,"Too many commandline parameters.\n");
  263. return(FAILED);
  264. }
  265. break;
  266. }
  267. } else {
  268. //parse_TK_data() =
  269. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  270. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  271. return(exit_status);
  272. }
  273. }
  274. //ap = dz->application;
  275. // parse_infile_and_hone_type() =
  276. if((exit_status = parse_infile_and_check_type(cmdline,dz))<0) {
  277. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  278. return(FAILED);
  279. }
  280. // setup_param_ranges_and_defaults() =
  281. if((exit_status = setup_the_param_ranges_and_defaults(dz))<0) {
  282. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  283. return(FAILED);
  284. }
  285. // open_first_infile CDP LIB
  286. if((exit_status = open_first_infile(cmdline[0],dz))<0) {
  287. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  288. return(FAILED);
  289. }
  290. cmdlinecnt--;
  291. cmdline++;
  292. // handle_outfile() =
  293. if(dz->mode < 3) { /* modes 4 & 5 stream output to stdout */
  294. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,is_launched,dz))<0) {
  295. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  296. return(FAILED);
  297. }
  298. }
  299. // handle_formants() redundant
  300. // handle_formant_quiksearch() redundant
  301. // handle_special_data() redundant
  302. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  303. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  304. return(FAILED);
  305. }
  306. //check_param_validity_and_consistency .....
  307. if((exit_status = check_the_param_validity_and_consistency(dz))<0) {
  308. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  309. return(FAILED);
  310. }
  311. is_launched = TRUE;
  312. //allocate_large_buffers() ... replaced by CDP LIB
  313. dz->extra_bufcnt = 0;
  314. dz->bptrcnt = 1;
  315. if((exit_status = establish_spec_bufptrs_and_extra_buffers(dz))<0) {
  316. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  317. return(FAILED);
  318. }
  319. if((exit_status = allocate_single_buffer(dz)) < 0) {
  320. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  321. return(FAILED);
  322. }
  323. //param_preprocess() redundant
  324. //spec_process_file =
  325. if((exit_status = features_scan(dz)) < 0) {
  326. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  327. return(FAILED);
  328. }
  329. if((exit_status = complete_output(dz))<0) { // CDP LIB
  330. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  331. return(FAILED);
  332. }
  333. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  334. free(dz);
  335. return(SUCCEEDED);
  336. }
  337. /**********************************************
  338. REPLACED CDP LIB FUNCTIONS
  339. **********************************************/
  340. /************************ HANDLE_THE_EXTRA_INFILE *********************/
  341. int handle_the_extra_infile(char ***cmdline,int *cmdlinecnt,dataptr dz)
  342. {
  343. /* OPEN ONE EXTRA ANALFILE, CHECK COMPATIBILITY */
  344. int exit_status;
  345. char *filename;
  346. fileptr fp2;
  347. int fileno = 1;
  348. double maxamp, maxloc;
  349. int maxrep;
  350. int getmax = 0, getmaxinfo = 0;
  351. infileptr ifp;
  352. fileptr fp1 = dz->infile;
  353. filename = (*cmdline)[0];
  354. if((dz->ifd[fileno] = sndopenEx(filename,0,CDP_OPEN_RDONLY)) < 0) {
  355. sprintf(errstr,"cannot open input file %s to read data.\n",filename);
  356. return(DATA_ERROR);
  357. }
  358. if((ifp = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  359. sprintf(errstr,"INSUFFICIENT MEMORY to store data on later infile. (1)\n");
  360. return(MEMORY_ERROR);
  361. }
  362. if((fp2 = (fileptr)malloc(sizeof(struct fileprops)))==NULL) {
  363. sprintf(errstr,"INSUFFICIENT MEMORY to store data on later infile. (2)\n");
  364. return(MEMORY_ERROR);
  365. }
  366. if((exit_status = readhead(ifp,dz->ifd[1],filename,&maxamp,&maxloc,&maxrep,getmax,getmaxinfo))<0)
  367. return(exit_status);
  368. copy_to_fileptr(ifp,fp2);
  369. if(fp2->filetype != ANALFILE) {
  370. sprintf(errstr,"%s is not an analysis file.\n",filename);
  371. return(DATA_ERROR);
  372. }
  373. if(fp2->origstype != fp1->origstype) {
  374. sprintf(errstr,"Incompatible original-sample-type in input file %s.\n",filename);
  375. return(DATA_ERROR);
  376. }
  377. if(fp2->origrate != fp1->origrate) {
  378. sprintf(errstr,"Incompatible original-sample-rate in input file %s.\n",filename);
  379. return(DATA_ERROR);
  380. }
  381. if(fp2->arate != fp1->arate) {
  382. sprintf(errstr,"Incompatible analysis-sample-rate in input file %s.\n",filename);
  383. return(DATA_ERROR);
  384. }
  385. if(fp2->Mlen != fp1->Mlen) {
  386. sprintf(errstr,"Incompatible analysis-window-length in input file %s.\n",filename);
  387. return(DATA_ERROR);
  388. }
  389. if(fp2->Dfac != fp1->Dfac) {
  390. sprintf(errstr,"Incompatible decimation factor in input file %s.\n",filename);
  391. return(DATA_ERROR);
  392. }
  393. if(fp2->channels != fp1->channels) {
  394. sprintf(errstr,"Incompatible channel-count in input file %s.\n",filename);
  395. return(DATA_ERROR);
  396. }
  397. if((dz->insams[fileno] = sndsizeEx(dz->ifd[fileno]))<0) { /* FIND SIZE OF FILE */
  398. sprintf(errstr, "Can't read size of input file %s.\n"
  399. "open_checktype_getsize_and_compareheader()\n",filename);
  400. return(PROGRAM_ERROR);
  401. }
  402. if(dz->insams[fileno]==0) {
  403. sprintf(errstr, "File %s contains no data.\n",filename);
  404. return(DATA_ERROR);
  405. }
  406. (*cmdline)++;
  407. (*cmdlinecnt)--;
  408. return(FINISHED);
  409. }
  410. /****************************** SET_PARAM_DATA *********************************/
  411. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  412. {
  413. ap->special_data = (char)special_data;
  414. ap->param_cnt = (char)paramcnt;
  415. ap->max_param_cnt = (char)maxparamcnt;
  416. if(ap->max_param_cnt>0) {
  417. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  418. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  419. return(MEMORY_ERROR);
  420. }
  421. strcpy(ap->param_list,paramlist);
  422. }
  423. return(FINISHED);
  424. }
  425. /****************************** SET_VFLGS *********************************/
  426. int set_vflgs
  427. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  428. {
  429. ap->option_cnt = (char) optcnt; /*RWD added cast */
  430. if(optcnt) {
  431. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  432. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  433. return(MEMORY_ERROR);
  434. }
  435. strcpy(ap->option_list,optlist);
  436. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  437. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  438. return(MEMORY_ERROR);
  439. }
  440. strcpy(ap->option_flags,optflags);
  441. }
  442. ap->vflag_cnt = (char) vflagcnt;
  443. ap->variant_param_cnt = (char) vparamcnt;
  444. if(vflagcnt) {
  445. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  446. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  447. return(MEMORY_ERROR);
  448. }
  449. strcpy(ap->variant_list,varlist);
  450. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  451. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  452. return(MEMORY_ERROR);
  453. }
  454. strcpy(ap->variant_flags,varflags);
  455. }
  456. return(FINISHED);
  457. }
  458. /***************************** APPLICATION_INIT **************************/
  459. int application_init(dataptr dz)
  460. {
  461. int exit_status;
  462. int storage_cnt;
  463. int tipc, brkcnt;
  464. aplptr ap = dz->application;
  465. if(ap->vflag_cnt>0)
  466. initialise_vflags(dz);
  467. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  468. ap->total_input_param_cnt = (char)tipc;
  469. if(tipc>0) {
  470. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  471. return(exit_status);
  472. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  473. return(exit_status);
  474. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  475. return(exit_status);
  476. }
  477. brkcnt = tipc;
  478. //THERE ARE NO INPUTFILE brktables USED IN THIS PROCESS
  479. if(brkcnt>0) {
  480. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  481. return(exit_status);
  482. }
  483. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  484. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  485. return(exit_status);
  486. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  487. return(exit_status);
  488. }
  489. if((exit_status = mark_parameter_types(dz,ap))<0)
  490. return(exit_status);
  491. // establish_infile_constants() replaced by
  492. dz->infilecnt = ONE_NONSND_FILE;
  493. //establish_bufptrs_and_extra_buffers():
  494. dz->array_cnt=2;
  495. if((dz->parray = (double **)malloc(dz->array_cnt * sizeof(double *)))==NULL) {
  496. sprintf(errstr,"INSUFFICIENT MEMORY for internal double arrays.\n");
  497. return(MEMORY_ERROR);
  498. }
  499. dz->parray[0] = NULL;
  500. dz->parray[1] = NULL;
  501. return(FINISHED);
  502. }
  503. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  504. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  505. {
  506. int n;
  507. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  508. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  509. return(MEMORY_ERROR);
  510. }
  511. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  512. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  513. return(MEMORY_ERROR);
  514. }
  515. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  516. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  517. return(MEMORY_ERROR);
  518. }
  519. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  520. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  521. return(MEMORY_ERROR);
  522. }
  523. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  524. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  525. return(MEMORY_ERROR);
  526. }
  527. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  528. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  529. return(MEMORY_ERROR);
  530. }
  531. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  532. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  533. return(MEMORY_ERROR);
  534. }
  535. for(n=0;n<brkcnt;n++) {
  536. dz->brk[n] = NULL;
  537. dz->brkptr[n] = NULL;
  538. dz->brkinit[n] = 0;
  539. dz->brksize[n] = 0;
  540. }
  541. return(FINISHED);
  542. }
  543. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  544. /* RWD mallo changed to calloc; helps debug verison run as release! */
  545. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  546. {
  547. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  548. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  549. return(MEMORY_ERROR);
  550. }
  551. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  552. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  553. return(MEMORY_ERROR);
  554. }
  555. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  556. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  557. return(MEMORY_ERROR);
  558. }
  559. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  560. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  561. return(MEMORY_ERROR);
  562. }
  563. return(FINISHED);
  564. }
  565. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  566. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  567. {
  568. int n;
  569. for(n=0;n<storage_cnt;n++) {
  570. dz->is_int[n] = (char)0;
  571. dz->no_brk[n] = (char)0;
  572. }
  573. return(FINISHED);
  574. }
  575. /***************************** MARK_PARAMETER_TYPES **************************/
  576. int mark_parameter_types(dataptr dz,aplptr ap)
  577. {
  578. int n, m; /* PARAMS */
  579. for(n=0;n<ap->max_param_cnt;n++) {
  580. switch(ap->param_list[n]) {
  581. case('0'): break; /* dz->is_active[n] = 0 is default */
  582. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  583. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  584. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  585. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  586. default:
  587. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  588. return(PROGRAM_ERROR);
  589. }
  590. } /* OPTIONS */
  591. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  592. switch(ap->option_list[n]) {
  593. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  594. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  595. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  596. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  597. default:
  598. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  599. return(PROGRAM_ERROR);
  600. }
  601. } /* VARIANTS */
  602. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  603. switch(ap->variant_list[n]) {
  604. case('0'): break;
  605. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  606. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  607. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  608. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  609. default:
  610. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  611. return(PROGRAM_ERROR);
  612. }
  613. } /* INTERNAL */
  614. for(n=0,
  615. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  616. switch(ap->internal_param_list[n]) {
  617. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  618. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  619. case('d'): dz->no_brk[m] = (char)1; break;
  620. default:
  621. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  622. return(PROGRAM_ERROR);
  623. }
  624. }
  625. return(FINISHED);
  626. }
  627. /***************************** HANDLE_THE_OUTFILE **************************/
  628. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,int is_launched,dataptr dz)
  629. {
  630. int exit_status, hasext = 0;
  631. char *filename = NULL;
  632. char ext[64], *p;
  633. strcpy(ext,".txt"); /* default extension */
  634. filename = (*cmdline)[0];
  635. strcpy(dz->outfilename,filename);
  636. p = dz->outfilename;
  637. while(*p != ENDOFSTR) {
  638. if(*p == '.') { /* overwrite dflt extension with user's extension, if it exists */
  639. hasext = 1;
  640. break;
  641. }
  642. p++;
  643. }
  644. switch(dz->mode) {
  645. case(FE_EVERY):
  646. case(FE_ENVEL):
  647. if(!sloom) {
  648. if(hasext) {
  649. p = dz->outfilename;
  650. while(*p != ENDOFSTR) {
  651. if(*p == '.') { /* overwrite dflt extension with user's extension, if it exists */
  652. strcpy(ext,p);
  653. *p = ENDOFSTR; /* remove any extension from outfilename */
  654. break;
  655. }
  656. p++;
  657. }
  658. }
  659. strcat(dz->outfilename,"0"); /* add numbering to 1st outfilename */
  660. strcat(dz->outfilename,ext); /* replace extension on outfilename */
  661. hasext = 1;
  662. }
  663. /* fall thro */
  664. case(FE_BEST):
  665. if(!sloom && !hasext)
  666. strcat(dz->outfilename,ext);
  667. if((exit_status = create_sized_outfile(dz->outfilename,dz))<0)
  668. return(exit_status);
  669. break;
  670. }
  671. (*cmdline)++;
  672. (*cmdlinecnt)--;
  673. return(FINISHED);
  674. }
  675. /***************************** ESTABLISH_APPLICATION **************************/
  676. int establish_application(dataptr dz)
  677. {
  678. aplptr ap;
  679. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  680. sprintf(errstr,"establish_application()\n");
  681. return(MEMORY_ERROR);
  682. }
  683. ap = dz->application;
  684. memset((char *)ap,0,sizeof(struct applic));
  685. return(FINISHED);
  686. }
  687. /************************* INITIALISE_VFLAGS *************************/
  688. int initialise_vflags(dataptr dz)
  689. {
  690. int n;
  691. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  692. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  693. return(MEMORY_ERROR);
  694. }
  695. for(n=0;n<dz->application->vflag_cnt;n++)
  696. dz->vflag[n] = FALSE;
  697. return FINISHED;
  698. }
  699. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  700. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  701. {
  702. int n;
  703. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  704. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  705. return(MEMORY_ERROR);
  706. }
  707. for(n=0;n<tipc;n++)
  708. ap->default_val[n] = 0.0;
  709. return(FINISHED);
  710. }
  711. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  712. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  713. {
  714. int n;
  715. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  716. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  717. return(MEMORY_ERROR);
  718. }
  719. for(n=0;n<tipc;n++)
  720. dz->is_active[n] = (char)0;
  721. return(FINISHED);
  722. }
  723. /************************* SETUP_THE_APPLICATION *******************/
  724. int setup_the_application(dataptr dz)
  725. {
  726. int exit_status;
  727. aplptr ap;
  728. if((exit_status = establish_application(dz))<0) // GLOBAL
  729. return(FAILED);
  730. ap = dz->application;
  731. dz->input_data_type = ANALFILE_ONLY;
  732. // SEE parstruct FOR EXPLANATION of next 2 functions
  733. switch(dz->mode) {
  734. case(FE_WINDOWS):
  735. /* mode 1: TEST MODE: creates data display of N windows at time K */
  736. if((exit_status = set_param_data(ap,0 ,11,7,"ddddiid0000"))<0) /* , lofrq, hifrq limits, N windows, time K*/
  737. return(FAILED);
  738. if((exit_status = set_vflgs(ap,"",0,"","s",1,0,"0"))<0)
  739. return(FAILED);
  740. dz->process_type = OTHER_PROCESS;
  741. dz->outfiletype = NO_OUTPUTFILE;
  742. break;
  743. case(FE_AVERAGE):
  744. /* mode 2: TEST MODE: creates data display of average peaks over spectrum from time A to time B */
  745. if((exit_status = set_param_data(ap,0 ,11,7,"ddddidd0000"))<0) /* lofrq, hifrq limits, time A, time B */
  746. return(FAILED);
  747. if((exit_status = set_vflgs(ap,"",0,"","s",1,0,"0"))<0)
  748. return(FAILED);
  749. dz->process_type = OTHER_PROCESS;
  750. dz->outfiletype = NO_OUTPUTFILE;
  751. break;
  752. case(FE_CHECK):
  753. /* mode 2: TEST MODE: display analysis window against peak data */
  754. if((exit_status = set_param_data(ap,0 ,11,6,"ddddid00000"))<0) /* lofrq, hifrq limits, time A, time B */
  755. return(FAILED);
  756. if((exit_status = set_vflgs(ap,"",0,"","s",1,0,"0"))<0)
  757. return(FAILED);
  758. dz->process_type = OTHER_PROCESS;
  759. dz->outfiletype = NO_OUTPUTFILE;
  760. break;
  761. case(FE_BEST):
  762. /* mode 3: EDIT TIMES OUTPUT: times to edit out loudest (or longest) example of each feature. */
  763. if((exit_status = set_param_data(ap,0 ,11,11,"ddddidddidd"))<0) /* lofrq, hifrq limits , 9 params */
  764. return(FAILED);
  765. if((exit_status = set_vflgs(ap,"",0,"","sd",2,0,"00"))<0) /* longest, rather than loudest, feature */
  766. return(FAILED);
  767. dz->process_type = TO_TEXTFILE;
  768. dz->outfiletype = TEXTFILE_OUT;
  769. break;
  770. case(FE_EVERY):
  771. /* mode 4: EDIT TIMES OUTPUT: times to edit out every example of J marks */
  772. if((exit_status = set_param_data(ap,0 ,11,11,"ddddidddidd"))<0) /* lofrq, hifrq limits , 9 params + no of marks to display */
  773. return(FAILED);
  774. if((exit_status = set_vflgs(ap,"",0,"","s",1,0,"0"))<0)
  775. return(FAILED);
  776. dz->process_type = TO_TEXTFILE;
  777. dz->outfiletype = TEXTFILE_OUT;
  778. break;
  779. case(FE_ENVEL):
  780. /* mode 5: ENVEL OUTPUT: times to envelope away everything except the marked items. */
  781. if((exit_status = set_param_data(ap,0 ,11,11,"ddddidddidd"))<0) /* lofrq, hifrq limits , 9 params */
  782. return(FAILED);
  783. if((exit_status = set_vflgs(ap,"",0,"","s",1,0,"0"))<0)
  784. return(FAILED);
  785. dz->process_type = TO_TEXTFILE;
  786. dz->outfiletype = TEXTFILE_OUT;
  787. break;
  788. default:
  789. sprintf(errstr,"Unknown mode\n");
  790. return(DATA_ERROR);
  791. }
  792. dz->has_otherfile = FALSE;
  793. return application_init(dz); //GLOBAL
  794. }
  795. /************************* PARSE_INFILE_AND_CHECK_TYPE *******************/
  796. int parse_infile_and_check_type(char **cmdline,dataptr dz)
  797. {
  798. int exit_status;
  799. infileptr infile_info;
  800. if(!sloom) {
  801. if((infile_info = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  802. sprintf(errstr,"INSUFFICIENT MEMORY for infile structure to test file data.");
  803. return(MEMORY_ERROR);
  804. } else if((exit_status = cdparse(cmdline[0],infile_info))<0) {
  805. sprintf(errstr,"Failed tp parse input file %s\n",cmdline[0]);
  806. return(PROGRAM_ERROR);
  807. } else if(infile_info->filetype != ANALFILE) {
  808. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  809. return(DATA_ERROR);
  810. } else if((exit_status = copy_parse_info_to_main_structure(infile_info,dz))<0) {
  811. sprintf(errstr,"Failed to copy file parsing information\n");
  812. return(PROGRAM_ERROR);
  813. }
  814. free(infile_info);
  815. }
  816. dz->clength = dz->wanted / 2;
  817. dz->chwidth = dz->nyquist/(double)dz->clength;
  818. dz->halfchwidth = dz->chwidth/2.0;
  819. return(FINISHED);
  820. }
  821. /************************* SETUP_THE_PARAM_RANGES_AND_DEFAULTS *******************/
  822. int setup_the_param_ranges_and_defaults(dataptr dz)
  823. {
  824. int exit_status;
  825. aplptr ap = dz->application;
  826. // set_param_ranges()
  827. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  828. // NB total_input_param_cnt is > 0 !!!s
  829. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  830. return(FAILED);
  831. // get_param_ranges()
  832. ap->lo[FE_LOFRQ] = MIDIMINFRQ; /* lofrq limit of peak search */
  833. ap->hi[FE_LOFRQ] = MIDIMAXFRQ;
  834. ap->default_val[FE_LOFRQ] = MIDDLE_C_FRQ;
  835. ap->lo[FE_HIFRQ] = MIDIMINFRQ; /* hifrq limit of peak search */
  836. ap->hi[FE_HIFRQ] = MIDIMAXFRQ;
  837. ap->default_val[FE_HIFRQ] = MIDIMAXFRQ;
  838. #ifdef EQUALFRQ
  839. ap->lo[FE_STEP] = dz->chwidth; /* stepsize for peak search (hz) */
  840. ap->hi[FE_STEP] = dz->nyquist / 2.0;
  841. ap->default_val[FE_STEP] = dz->chwidth;
  842. ap->lo[FE_WINSIZE] = dz->chwidth; /* sizeof window over which amps averaged to find peak location (hz) */
  843. ap->hi[FE_WINSIZE] = DFLT_MAX_AVWIN_SIZE;
  844. ap->default_val[FE_WINSIZE] = FE_WINSIZ_DFLT;
  845. #else
  846. ap->lo[FE_STEP] = 0.1; /* stepsize for peak search (semitones) */
  847. ap->hi[FE_STEP] = SEMITONES_PER_OCTAVE;
  848. ap->default_val[FE_STEP] = DFLT_PK_STEP;
  849. ap->lo[FE_WINSIZE] = 0.1; /* sizeof window over which amps averaged to find peak location (semitones) */
  850. ap->hi[FE_WINSIZE] = SEMITONES_PER_OCTAVE * 2.0;
  851. ap->default_val[FE_WINSIZE] = MAJOR_3RD;
  852. #endif
  853. ap->lo[FE_PKCNT] = 1; /* no of peaks to search for */
  854. ap->hi[FE_PKCNT] = FE_MAX_PKCNT;
  855. ap->default_val[FE_PKCNT] = DFLT_PEAKS_CNT;
  856. switch(dz->mode) {
  857. case(FE_WINDOWS):
  858. /* mode 1: TEST MODE: creates data display of N windows at time K */
  859. ap->lo[FE_WINCNT] = 1; /* no of windows to display */
  860. ap->hi[FE_WINCNT] = dz->wlength;
  861. ap->default_val[FE_WINCNT] = 1;
  862. ap->lo[FE_WINTIME] = 0.0; /* time of first window to display */
  863. ap->hi[FE_WINTIME] = dz->duration;
  864. ap->default_val[FE_WINTIME] = dz->duration/2.0;
  865. break;
  866. case(FE_AVERAGE):
  867. /* mode 2: TEST MODE: creates data display of average peaks over spectrum from time A to time B */
  868. ap->lo[FE_START] = 0.0; /* start time in sound */
  869. ap->hi[FE_START] = dz->duration;
  870. ap->default_val[FE_START] = 0.0;
  871. ap->lo[FE_END] = 0.0; /* end time in sound */
  872. ap->hi[FE_END] = dz->duration;
  873. ap->default_val[FE_END] = dz->duration;
  874. break;
  875. case(FE_CHECK):
  876. /* mode 2: TEST MODE: creates data display of average peaks over spectrum from time A to time B */
  877. ap->lo[FE_START] = 0.0; /* start time in sound */
  878. ap->hi[FE_START] = dz->duration;
  879. ap->default_val[FE_START] = dz->duration/2.0;
  880. break;
  881. case(FE_BEST):
  882. case(FE_EVERY):
  883. case(FE_ENVEL):
  884. ap->lo[FE_MIN] = dz->frametime * SECS_TO_MS; /* min dur of any feature to take note of (ms) */
  885. ap->hi[FE_MIN] = dz->duration * SECS_TO_MS;
  886. ap->default_val[FE_MIN] = (int)round((MIN_FE_DUR * MS_TO_SECS)/dz->frametime) * dz->frametime * SECS_TO_MS;
  887. ap->lo[FE_MAX] = dz->frametime * SECS_TO_MS; /* max dur of any feature to take note of (ms) */
  888. ap->hi[FE_MAX] = dz->duration * SECS_TO_MS;
  889. ap->default_val[FE_MAX] = DFLT_MAX_FE_LEN;
  890. ap->lo[FE_ERROR] = 0.0; /* error in peak equivalence (semitones) */
  891. ap->hi[FE_ERROR] = SEMITONES_PER_OCTAVE;
  892. ap->default_val[FE_ERROR] = DFLT_PK_ERROR;
  893. ap->lo[FE_FECNT] = 1; /* no of features to rank (in order of number of occurences) */
  894. ap->hi[FE_FECNT] = FE_CNT_MAX;
  895. ap->default_val[FE_FECNT] = FE_CNT_TYPICAL;
  896. ap->lo[FE_TAIL] = 0.0; /* ms of sound before and after feature to retain when it is edited out */
  897. ap->hi[FE_TAIL] = FE_TAILMAX;
  898. ap->default_val[FE_TAIL] = FE_TAILDUR;
  899. ap->lo[FE_SPLICE] = 1.0; /* splicelen (mS) */
  900. ap->hi[FE_SPLICE] = FE_SPLICEMAX;
  901. ap->default_val[FE_SPLICE] = FE_SPLICELEN;
  902. break;
  903. }
  904. if(!sloom)
  905. put_default_vals_in_all_params(dz);
  906. return(FINISHED);
  907. }
  908. /********************************* PARSE_SLOOM_DATA *********************************/
  909. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  910. {
  911. int exit_status;
  912. int cnt = 1, infilecnt;
  913. int filesize, insams, inbrksize;
  914. double dummy;
  915. int true_cnt = 0;
  916. //aplptr ap;
  917. while(cnt<=PRE_CMDLINE_DATACNT) {
  918. if(cnt > argc) {
  919. sprintf(errstr,"Insufficient data sent from TK\n");
  920. return(DATA_ERROR);
  921. }
  922. switch(cnt) {
  923. case(1):
  924. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  925. sprintf(errstr,"Cannot read process no. sent from TK\n");
  926. return(DATA_ERROR);
  927. }
  928. break;
  929. case(2):
  930. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  931. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  932. return(DATA_ERROR);
  933. }
  934. if(dz->mode > 0)
  935. dz->mode--;
  936. //setup_particular_application() =
  937. if((exit_status = setup_the_application(dz))<0)
  938. return(exit_status);
  939. //ap = dz->application;
  940. break;
  941. case(3):
  942. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  943. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  944. return(DATA_ERROR);
  945. }
  946. if(infilecnt < 1) {
  947. true_cnt = cnt + 1;
  948. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  949. }
  950. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  951. return(exit_status);
  952. break;
  953. case(INPUT_FILETYPE+4):
  954. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  955. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  956. return(DATA_ERROR);
  957. }
  958. break;
  959. case(INPUT_FILESIZE+4):
  960. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  961. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  962. return(DATA_ERROR);
  963. }
  964. dz->insams[0] = filesize;
  965. break;
  966. case(INPUT_INSAMS+4):
  967. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  968. sprintf(errstr,"Cannot read insams sent from TK\n");
  969. return(DATA_ERROR);
  970. }
  971. dz->insams[0] = insams;
  972. break;
  973. case(INPUT_SRATE+4):
  974. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  975. sprintf(errstr,"Cannot read srate sent from TK\n");
  976. return(DATA_ERROR);
  977. }
  978. break;
  979. case(INPUT_CHANNELS+4):
  980. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  981. sprintf(errstr,"Cannot read channels sent from TK\n");
  982. return(DATA_ERROR);
  983. }
  984. break;
  985. case(INPUT_STYPE+4):
  986. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  987. sprintf(errstr,"Cannot read stype sent from TK\n");
  988. return(DATA_ERROR);
  989. }
  990. break;
  991. case(INPUT_ORIGSTYPE+4):
  992. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  993. sprintf(errstr,"Cannot read origstype sent from TK\n");
  994. return(DATA_ERROR);
  995. }
  996. break;
  997. case(INPUT_ORIGRATE+4):
  998. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  999. sprintf(errstr,"Cannot read origrate sent from TK\n");
  1000. return(DATA_ERROR);
  1001. }
  1002. break;
  1003. case(INPUT_MLEN+4):
  1004. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  1005. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  1006. return(DATA_ERROR);
  1007. }
  1008. break;
  1009. case(INPUT_DFAC+4):
  1010. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  1011. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  1012. return(DATA_ERROR);
  1013. }
  1014. break;
  1015. case(INPUT_ORIGCHANS+4):
  1016. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  1017. sprintf(errstr,"Cannot read origchans sent from TK\n");
  1018. return(DATA_ERROR);
  1019. }
  1020. break;
  1021. case(INPUT_SPECENVCNT+4):
  1022. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  1023. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  1024. return(DATA_ERROR);
  1025. }
  1026. dz->specenvcnt = dz->infile->specenvcnt;
  1027. break;
  1028. case(INPUT_WANTED+4):
  1029. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  1030. sprintf(errstr,"Cannot read wanted sent from TK\n");
  1031. return(DATA_ERROR);
  1032. }
  1033. break;
  1034. case(INPUT_WLENGTH+4):
  1035. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  1036. sprintf(errstr,"Cannot read wlength sent from TK\n");
  1037. return(DATA_ERROR);
  1038. }
  1039. break;
  1040. case(INPUT_OUT_CHANS+4):
  1041. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  1042. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  1043. return(DATA_ERROR);
  1044. }
  1045. break;
  1046. /* RWD these chanegs to samps - tk will have to deal with that! */
  1047. case(INPUT_DESCRIPTOR_BYTES+4):
  1048. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  1049. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  1050. return(DATA_ERROR);
  1051. }
  1052. break;
  1053. case(INPUT_IS_TRANSPOS+4):
  1054. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  1055. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  1056. return(DATA_ERROR);
  1057. }
  1058. break;
  1059. case(INPUT_COULD_BE_TRANSPOS+4):
  1060. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  1061. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  1062. return(DATA_ERROR);
  1063. }
  1064. break;
  1065. case(INPUT_COULD_BE_PITCH+4):
  1066. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  1067. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  1068. return(DATA_ERROR);
  1069. }
  1070. break;
  1071. case(INPUT_DIFFERENT_SRATES+4):
  1072. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  1073. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  1074. return(DATA_ERROR);
  1075. }
  1076. break;
  1077. case(INPUT_DUPLICATE_SNDS+4):
  1078. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  1079. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  1080. return(DATA_ERROR);
  1081. }
  1082. break;
  1083. case(INPUT_BRKSIZE+4):
  1084. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  1085. sprintf(errstr,"Cannot read brksize sent from TK\n");
  1086. return(DATA_ERROR);
  1087. }
  1088. if(inbrksize > 0) {
  1089. switch(dz->input_data_type) {
  1090. case(WORDLIST_ONLY):
  1091. break;
  1092. case(PITCH_AND_PITCH):
  1093. case(PITCH_AND_TRANSPOS):
  1094. case(TRANSPOS_AND_TRANSPOS):
  1095. dz->tempsize = inbrksize;
  1096. break;
  1097. case(BRKFILES_ONLY):
  1098. case(UNRANGED_BRKFILE_ONLY):
  1099. case(DB_BRKFILES_ONLY):
  1100. case(ALL_FILES):
  1101. case(ANY_NUMBER_OF_ANY_FILES):
  1102. if(dz->extrabrkno < 0) {
  1103. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  1104. return(DATA_ERROR);
  1105. }
  1106. if(dz->brksize == NULL) {
  1107. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  1108. return(PROGRAM_ERROR);
  1109. }
  1110. dz->brksize[dz->extrabrkno] = inbrksize;
  1111. break;
  1112. default:
  1113. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  1114. dz->input_data_type);
  1115. return(PROGRAM_ERROR);
  1116. }
  1117. break;
  1118. }
  1119. break;
  1120. case(INPUT_NUMSIZE+4):
  1121. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  1122. sprintf(errstr,"Cannot read numsize sent from TK\n");
  1123. return(DATA_ERROR);
  1124. }
  1125. break;
  1126. case(INPUT_LINECNT+4):
  1127. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  1128. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  1129. return(DATA_ERROR);
  1130. }
  1131. break;
  1132. case(INPUT_ALL_WORDS+4):
  1133. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  1134. sprintf(errstr,"Cannot read all_words sent from TK\n");
  1135. return(DATA_ERROR);
  1136. }
  1137. break;
  1138. case(INPUT_ARATE+4):
  1139. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  1140. sprintf(errstr,"Cannot read arate sent from TK\n");
  1141. return(DATA_ERROR);
  1142. }
  1143. break;
  1144. case(INPUT_FRAMETIME+4):
  1145. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  1146. sprintf(errstr,"Cannot read frametime sent from TK\n");
  1147. return(DATA_ERROR);
  1148. }
  1149. dz->frametime = (float)dummy;
  1150. break;
  1151. case(INPUT_WINDOW_SIZE+4):
  1152. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  1153. sprintf(errstr,"Cannot read window_size sent from TK\n");
  1154. return(DATA_ERROR);
  1155. }
  1156. break;
  1157. case(INPUT_NYQUIST+4):
  1158. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  1159. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  1160. return(DATA_ERROR);
  1161. }
  1162. break;
  1163. case(INPUT_DURATION+4):
  1164. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  1165. sprintf(errstr,"Cannot read duration sent from TK\n");
  1166. return(DATA_ERROR);
  1167. }
  1168. break;
  1169. case(INPUT_MINBRK+4):
  1170. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  1171. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  1172. return(DATA_ERROR);
  1173. }
  1174. break;
  1175. case(INPUT_MAXBRK+4):
  1176. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  1177. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  1178. return(DATA_ERROR);
  1179. }
  1180. break;
  1181. case(INPUT_MINNUM+4):
  1182. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  1183. sprintf(errstr,"Cannot read minnum sent from TK\n");
  1184. return(DATA_ERROR);
  1185. }
  1186. break;
  1187. case(INPUT_MAXNUM+4):
  1188. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  1189. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  1190. return(DATA_ERROR);
  1191. }
  1192. break;
  1193. default:
  1194. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  1195. return(PROGRAM_ERROR);
  1196. }
  1197. cnt++;
  1198. }
  1199. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  1200. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  1201. return(DATA_ERROR);
  1202. }
  1203. if(true_cnt)
  1204. cnt = true_cnt;
  1205. *cmdlinecnt = 0;
  1206. while(cnt < argc) {
  1207. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  1208. return(exit_status);
  1209. cnt++;
  1210. }
  1211. return(FINISHED);
  1212. }
  1213. /********************************* GET_TK_CMDLINE_WORD *********************************/
  1214. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  1215. {
  1216. if(*cmdlinecnt==0) {
  1217. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  1218. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  1219. return(MEMORY_ERROR);
  1220. }
  1221. } else {
  1222. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  1223. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  1224. return(MEMORY_ERROR);
  1225. }
  1226. }
  1227. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  1228. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  1229. return(MEMORY_ERROR);
  1230. }
  1231. strcpy((*cmdline)[*cmdlinecnt],q);
  1232. (*cmdlinecnt)++;
  1233. return(FINISHED);
  1234. }
  1235. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  1236. int assign_file_data_storage(int infilecnt,dataptr dz)
  1237. {
  1238. int exit_status;
  1239. int no_sndfile_system_files = FALSE;
  1240. dz->infilecnt = infilecnt;
  1241. if((exit_status = allocate_filespace(dz))<0)
  1242. return(exit_status);
  1243. if(no_sndfile_system_files)
  1244. dz->infilecnt = 0;
  1245. return(FINISHED);
  1246. }
  1247. /*********************** CHECK_THE_PARAM_VALIDITY_AND_CONSISTENCY *********************/
  1248. int check_the_param_validity_and_consistency(dataptr dz)
  1249. {
  1250. double diff;
  1251. if(dz->param[FE_HIFRQ] - dz->param[FE_LOFRQ] < dz->chwidth * 2.0) {
  1252. sprintf(errstr,"Low frequency and high frequency limits of search are too close.");
  1253. return(USER_ERROR);
  1254. }
  1255. #ifdef EQUALFRQ
  1256. if(dz->param[FE_HIFRQ] - dz->param[FE_LOFRQ] < dz->param[FE_STEP]) {
  1257. sprintf(errstr,"Low frequency and high frequency limits of search are too close for the stepsize specified.");
  1258. return(USER_ERROR);
  1259. }
  1260. #else
  1261. if(dz->param[FE_HIFRQ]/dz->param[FE_LOFRQ] < pow(2.0,(dz->param[FE_STEP] * 2.0)/SEMITONES_PER_OCTAVE)) {
  1262. sprintf(errstr,"Low frequency and high frequency limits of search are too close for the stepsize specified.");
  1263. return(USER_ERROR);
  1264. }
  1265. #endif
  1266. switch(dz->mode) {
  1267. case(FE_WINDOWS):
  1268. if(dz->duration - (dz->iparam[FE_WINCNT] * dz->frametime) <= dz->param[FE_WINTIME]) {
  1269. sprintf(errstr,"Time of window to display is too close to end, for the windowcnt specified.");
  1270. return(USER_ERROR);
  1271. }
  1272. dz->iparam[FE_WINTIME] = (int)round(dz->param[FE_WINTIME]/dz->frametime);
  1273. break;
  1274. case(FE_CHECK):
  1275. dz->iparam[FE_START] = (int)round(dz->param[FE_START]/dz->frametime);
  1276. dz->iparam[FE_START] = min(dz->wlength - 1,dz->iparam[FE_START]);
  1277. break;
  1278. case(FE_AVERAGE):
  1279. if((diff = dz->param[FE_END] - dz->param[FE_START]) < 0.0) {
  1280. sprintf(errstr,"Start and End times are incompatible.");
  1281. return(USER_ERROR);
  1282. }
  1283. if((dz->iparam[FE_START] = (int)round(dz->param[FE_START]/dz->frametime)) >= dz->wlength)
  1284. dz->iparam[FE_START] = dz->wlength - 1;
  1285. if((dz->iparam[FE_END] = (int)round(dz->param[FE_END]/dz->frametime)) >= dz->wlength)
  1286. dz->iparam[FE_END] = dz->wlength;
  1287. if(dz->iparam[FE_START] == dz->iparam[FE_END])
  1288. dz->iparam[FE_END]++;
  1289. break;
  1290. case(FE_BEST):
  1291. case(FE_EVERY):
  1292. case(FE_ENVEL):
  1293. if(dz->param[FE_MAX] - dz->param[FE_MIN] < 0.0) {
  1294. sprintf(errstr,"Maximum and minimum feature length are incompatible.");
  1295. return(USER_ERROR);
  1296. }
  1297. if(dz->param[FE_STEP] >= dz->param[FE_WINSIZE]) {
  1298. sprintf(errstr,"Step in searching for peaks must be less than peak-window-size.");
  1299. return(USER_ERROR);
  1300. }
  1301. break;
  1302. }
  1303. return FINISHED;
  1304. }
  1305. /************************* redundant functions: to ensure libs compile OK *******************/
  1306. int assign_process_logic(dataptr dz)
  1307. {
  1308. return(FINISHED);
  1309. }
  1310. void set_legal_infile_structure(dataptr dz)
  1311. {}
  1312. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  1313. {
  1314. return(FINISHED);
  1315. }
  1316. int setup_internal_arrays_and_array_pointers(dataptr dz)
  1317. {
  1318. return(FINISHED);
  1319. }
  1320. int establish_bufptrs_and_extra_buffers(dataptr dz)
  1321. {
  1322. return(FINISHED);
  1323. }
  1324. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1325. {
  1326. return(FINISHED);
  1327. }
  1328. int read_special_data(char *str,dataptr dz)
  1329. {
  1330. return(FINISHED);
  1331. }
  1332. int inner_loop
  1333. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  1334. {
  1335. return(FINISHED);
  1336. }
  1337. /********************************************************************************************/
  1338. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1339. {
  1340. if (!strcmp(prog_identifier_from_cmdline,"get")) dz->process = FEATURES;
  1341. else {
  1342. sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  1343. return(USAGE_ONLY);
  1344. }
  1345. return(FINISHED);
  1346. }
  1347. /******************************** USAGE1 ********************************/
  1348. int usage1(void)
  1349. {
  1350. fprintf(stderr,
  1351. "Use an anlysis file to find the MOST PROMINENT FEATURES in a sound source.\n"
  1352. "\n"
  1353. "Mode 1: Create data to cut best example of each prominent feature from sound source.\n"
  1354. "\n"
  1355. "Mode 2: Create data to cut out all examples of 1 (or more) prominent feature(s).\n"
  1356. " Creates 1 outfile per output feature.\n"
  1357. "\n"
  1358. "Mode 3: Create data-files to envelope the source so only 1 feature remains.\n"
  1359. " Creates 1 envelope file per extracted feature.\n"
  1360. "\n"
  1361. "Mode 4: Output peak data for 1 or more windows at a specified time in file.\n"
  1362. "\n"
  1363. "Mode 5: Output statistics showing most prominent peak frqs in time-slot selected.\n"
  1364. "\n"
  1365. "Mode 6: Output display spectrum + peaks, to check if peaks credible.\n"
  1366. "\n"
  1367. "Type 'features get' for more information.\n");
  1368. return(USAGE_ONLY);
  1369. }
  1370. /******************************** USAGE2 ********************************/
  1371. int usage2(char *str)
  1372. {
  1373. if(!strcmp(str,"get")) {
  1374. fprintf(stderr,
  1375. "USAGE: features get 1-3 inanalfile outname lof hif step winsiz pkcnt [PARAMS]\n"
  1376. "OR: features get 4-6 inanalfile lof hif step winsiz pkcnt [PARAMS]\n"
  1377. "\n"
  1378. "To find what each of the 5 modes does, type 'features'.\n"
  1379. "\n"
  1380. "PARAMS are ...\n"
  1381. "(mode 1) min max error featurecnt tail splice [-s] [-d]\n"
  1382. "(mode 2-3) min max error featurecnt tail splice [-s] \n"
  1383. "(mode 4) wincnt time [-s]\n"
  1384. "(mode 5) starttime endtime [-s]\n"
  1385. "(mode 6) time [-s]\n"
  1386. "\n"
  1387. "LOF lowest frq to search for spectral peaks (%.0lf - %.0lf: dflt %.0lf)\n"
  1388. "HIF highest frq to search for spectral peaks (%.0lf - %.0lf: dflt %.0lf)\n"
  1389. #ifdef EQUALFRQ
  1390. "STEP minimum distance between peaks (hz) (chanwidth - nyqist/2: dflt chwdith)\n"
  1391. "WINSIZ scan-windowsize for peak search (hz) (chanwidth - %.0lf: dflt %.0lf)\n"
  1392. #else
  1393. "STEP minimum distance between peaks (semitones) (%.1lf - %.0lf: dflt %.0lf)\n"
  1394. "WINSIZ scan-windowsize for peak search (semitones) (%.1lf - %.0lf: dflt %.0lf)\n"
  1395. #endif
  1396. "PKCNT number of peaks to locate (1 - %d: dflt %d)\n"
  1397. "MIN minimum size of features to find (mS) (%d - filelen: dflt %d)\n"
  1398. "MAX maximum size of features to find (mS) (%d - filelen: dflt %d)\n"
  1399. "ERROR acceptable error in equating peaks (semitones) (0 - %.0lf: dflt %.0lf)\n"
  1400. "FEATURECNT max number of features to find (1 - %d: dflt %d)\n"
  1401. "TAIL length of snd to keep before and after feature (mS) (0 - %d: dflt %d))\n"
  1402. "SPLICE splicelength for feature extraction (mS) (1 - %d: dflt %d))\n"
  1403. "-s Sort the analysis data into frq order, before searching for peaks.\n"
  1404. "-d extract longest examples (default: extract loudest examples)\n"
  1405. "\n"
  1406. "WINCNT number of windows to output (1 - %d)\n"
  1407. "TIME time of (first) window to output (0 - filelen).\n"
  1408. "\n"
  1409. "STARTTIME start time in sound (0 - filelen)\n"
  1410. "ENDTIME end time in sound (0 - filelen)\n"
  1411. "\n",ceil(MIDIMINFRQ),floor(MIDIMAXFRQ),MIDDLE_C_FRQ,ceil(MIDIMINFRQ),floor(MIDIMAXFRQ),floor(MIDIMAXFRQ),
  1412. #ifdef EQUALFRQ
  1413. DFLT_MAX_AVWIN_SIZE,FE_WINSIZ_DFLT,
  1414. #else
  1415. 0.1,SEMITONES_PER_OCTAVE,DFLT_PK_STEP,
  1416. 0.1,SEMITONES_PER_OCTAVE * 2.0,MAJOR_3RD,
  1417. #endif
  1418. FE_MAX_PKCNT,DFLT_PEAKS_CNT,
  1419. MIN_FE_DUR,MIN_FE_DUR,
  1420. MIN_FE_DUR,DFLT_MAX_FE_LEN,
  1421. SEMITONES_PER_OCTAVE,DFLT_PK_ERROR,
  1422. FE_CNT_MAX,FE_CNT_TYPICAL,
  1423. FE_TAILMAX,FE_TAILDUR,
  1424. FE_SPLICEMAX,FE_SPLICELEN,
  1425. FE_MAX_WIN);
  1426. } else
  1427. fprintf(stdout,"Unknown option '%s'\n",str);
  1428. return(USAGE_ONLY);
  1429. }
  1430. int usage3(char *str1,char *str2)
  1431. {
  1432. fprintf(stderr,"Insufficient parameters on command line.\n");
  1433. return(USAGE_ONLY);
  1434. }
  1435. /*********************** GET_THE_MODE_NO ***************************/
  1436. int get_the_mode_no(char *str, dataptr dz)
  1437. {
  1438. if(sscanf(str,"%d",&dz->mode)!=1) {
  1439. sprintf(errstr,"Cannot read mode of program.\n");
  1440. return(USAGE_ONLY);
  1441. }
  1442. if(dz->mode <= 0 || dz->mode > dz->maxmode) {
  1443. sprintf(errstr,"Program mode value [%d] is out of range [1 - %d].\n",dz->mode,dz->maxmode);
  1444. return(USAGE_ONLY);
  1445. }
  1446. dz->mode--; /* CHANGE TO INTERNAL REPRESENTATION OF MODE NO */
  1447. return(FINISHED);
  1448. }
  1449. /*********************** FEATURES_SCAN ***************************
  1450. *
  1451. * Examimes each analysis-window, using a peak(searching)-window to find peaks in the analysis-window.
  1452. */
  1453. #define SAFETY_MARGIN (8)
  1454. int features_scan(dataptr dz)
  1455. {
  1456. int wc, cc, vc, n, lastminampchan, lastmaxampchan, lookformax, peakcnt, minpkpos=0, wins_in_buf, OK;
  1457. double lastminamp, lastmaxamp, botfrq, interval;
  1458. double intv_errorbnd, intv_to_next_window, intv_to_centre_of_window, intv_to_top_of_window, intv_to_top_of_srch, intv_to_bot_of_srch;
  1459. double lastmaxampchanfrq, lastminampchanfrq, maxamp, thisval, ampsum;
  1460. #ifndef EQUALFRQ
  1461. double minmidi;
  1462. #endif
  1463. int *win_peakchan;
  1464. int k, j, startwin, endwin, *peakstats=NULL;
  1465. float **peakamp=NULL, **peakfrq=NULL, *win_peakfrq;
  1466. float *win_peakamp, *totamp=NULL;
  1467. /* ARRAYS FOR FEATURE ANALYSIS */
  1468. if(dz->mode != FE_CHECK) {
  1469. if((peakamp = (float **)malloc(dz->wlength * sizeof(float *)))==NULL) { /* Array to store all peaks amplitude data */
  1470. sprintf(errstr,"INSUFFICIENT MEMORY to store amplitudes pointers for all possible peaks.\n");
  1471. return(MEMORY_ERROR);
  1472. }
  1473. if((peakfrq = (float **)malloc(dz->wlength * sizeof(float *)))==NULL) { /* Array to store all peaks frq data */
  1474. sprintf(errstr,"INSUFFICIENT MEMORY to store frequency pointers for all possible peaks.\n");
  1475. return(MEMORY_ERROR);
  1476. }
  1477. for(k = 0;k < dz->wlength; k++) {
  1478. if((peakamp[k] = (float *)malloc(dz->iparam[FE_PKCNT] * sizeof(float)))==NULL) { /* Arrays to store all peaks amplitude data */
  1479. sprintf(errstr,"INSUFFICIENT MEMORY to store amplitudes for all possible peaks.\n");
  1480. return(MEMORY_ERROR);
  1481. }
  1482. for(j = 0;j < dz->param[FE_PKCNT];j++)
  1483. peakamp[k][j] = (float)0.0;
  1484. if((peakfrq[k] = (float *)malloc(dz->iparam[FE_PKCNT] * sizeof(float)))==NULL) { /* Arrays to store all peaks frq data */
  1485. sprintf(errstr,"INSUFFICIENT MEMORY to store frequencies for all possible peaks.\n");
  1486. return(MEMORY_ERROR);
  1487. }
  1488. for(j = 0;j < dz->param[FE_PKCNT];j++)
  1489. peakfrq[k][j] = (float)0.0;
  1490. }
  1491. }
  1492. if(dz->mode == FE_WINDOWS) {
  1493. if((totamp = (float *)malloc(dz->wlength * sizeof(float *)))==NULL) { /* Array to store all WINDOW amplitude data */
  1494. sprintf(errstr,"INSUFFICIENT MEMORY to store window amplitudes for all windows.\n");
  1495. return(MEMORY_ERROR);
  1496. }
  1497. //silence = pow(10.0,(MIN_DB/20.0));
  1498. }
  1499. /* ARRAYS AND COINSTANTS FOR PEAK SEARCHING IN ANALYSIS WINDOW */
  1500. #ifdef EQUALFRQ
  1501. interval = dz->param[FE_HIFRQ] - dz->param[FE_LOFRQ];
  1502. #else
  1503. interval = unchecked_hztomidi(dz->param[FE_HIFRQ]) - unchecked_hztomidi(dz->param[FE_LOFRQ]);
  1504. #endif
  1505. peakcnt = (int)ceil(interval/dz->param[FE_STEP]) + SAFETY_MARGIN;
  1506. if((win_peakchan = (int *)malloc(peakcnt * sizeof(int)))==NULL) { /* Array to store peaks found in an analysis-window */
  1507. sprintf(errstr,"INSUFFICIENT MEMORY to store window peak channel data.\n");
  1508. return(MEMORY_ERROR);
  1509. }
  1510. if((win_peakamp = (float *)malloc(peakcnt * sizeof(float)))==NULL) { /* Array to store peaks found in an analysis-window */
  1511. sprintf(errstr,"INSUFFICIENT MEMORY to store window peak amplitude data.\n");
  1512. return(MEMORY_ERROR);
  1513. }
  1514. if((win_peakfrq = (float *)malloc(peakcnt * sizeof(float)))==NULL) { /* Array to store peaks found in an analysis-window */
  1515. sprintf(errstr,"INSUFFICIENT MEMORY to store window peak frequency data.\n");
  1516. return(MEMORY_ERROR);
  1517. }
  1518. if(dz->mode == FE_AVERAGE) {
  1519. if((peakstats = (int *)malloc(peakcnt * sizeof(int)))==NULL) { /* Array to store peaks found in an analysis-window */
  1520. sprintf(errstr,"INSUFFICIENT MEMORY to store window peak statistics data.\n");
  1521. return(MEMORY_ERROR);
  1522. }
  1523. memset((char *)peakstats,0,peakcnt * sizeof(int));
  1524. }
  1525. #ifdef EQUALFRQ
  1526. intv_to_next_window = dz->param[FE_STEP];
  1527. intv_to_centre_of_window = dz->param[FE_WINSIZE] / 2.0;
  1528. intv_to_top_of_window = dz->param[FE_WINSIZE];
  1529. /* we search for possible data over a group of channels that is slightly larger than the peak-window = search-window */
  1530. /* just in case any frequency data is not in anticipated channel : to find the channel limits of srch, generate frqs that (theoretically) */
  1531. /* correspond to those channels ..... */
  1532. intv_to_top_of_srch = dz->param[FE_WINSIZE] + (FRQ_SRCH_ERRORBND * dz->chwidth);
  1533. intv_to_bot_of_srch = -(FRQ_SRCH_ERRORBND * dz->chwidth);
  1534. #else
  1535. intv_to_next_window = semit_to_ratio(dz->param[FE_STEP]);
  1536. intv_to_centre_of_window = semit_to_ratio(dz->param[FE_WINSIZE] / 2.0);
  1537. intv_to_top_of_window = semit_to_ratio(dz->param[FE_WINSIZE]);
  1538. /* we search for possible data over a group of channels that is slightly larger than the peak-window = search-window */
  1539. /* just in case any frequency data is not in anticipated channel : to find the channel limits of srch, generate frqs that (theoretically) */
  1540. /* correspond to those channels ..... */
  1541. intv_to_top_of_srch = semit_to_ratio(dz->param[FE_WINSIZE] + FRQ_SRCH_ERRORBND);
  1542. intv_to_bot_of_srch = semit_to_ratio(-FRQ_SRCH_ERRORBND);
  1543. #endif
  1544. intv_errorbnd = semit_to_ratio(FRQ_SRCH_ERRORBND);
  1545. /* EXTRACT PEAK INFO FROM ANALYSIS WINDOWS */
  1546. if(dz->mode == FE_CHECK) {
  1547. if((sndseekEx(dz->ifd[0],dz->iparam[FE_START] * dz->wanted,0)<0)){
  1548. sprintf(errstr,"sndseek() failed\n");
  1549. return SYSTEM_ERROR;
  1550. }
  1551. if((dz->ssampsread = fgetfbufEx(dz->bigfbuf,dz->wanted,dz->ifd[0],0)) < 0) {
  1552. sprintf(errstr,"Can't read samples from input soundfile\n");
  1553. return(SYSTEM_ERROR);
  1554. }
  1555. lastminamp = HUGE; /* forces 1st minamp value to be less than previous minamp position */
  1556. lastminampchan = 0;
  1557. lastmaxampchanfrq = -(dz->nyquist); /* forces first minampchanfrq to be greater than lastmaxampchanfrq */
  1558. lastmaxamp = -HUGE; /* forces 1st maxamp value to be greater than previous maxamp position */
  1559. lastmaxampchan = -1;
  1560. lastminampchanfrq = -(dz->nyquist); /* forces first maxampchanfrq to be greater than lastminampchanfrq */
  1561. lookformax = 1; /* always begin by searching for a maximum (lastmaxamp set to -HUGE) */
  1562. peakcnt = 0; /* initialise peak counter */
  1563. botfrq = dz->param[FE_LOFRQ] / intv_to_centre_of_window; /* initialise bottom frq of 1st peak-window to search */
  1564. /* FIND ALL THE PEAKS IN THE WINDOW --> array of peak trof [peak trof ......] in 'win_peakchan' */
  1565. /* NEW */
  1566. if(dz->vflag[FE_SORTBUF])
  1567. frqsort_buf(dz->bigfbuf,dz);
  1568. /* NEW */
  1569. peakcnt = peaks_in_window(botfrq,intv_to_bot_of_srch,intv_to_top_of_srch,intv_to_centre_of_window,intv_to_top_of_window,intv_to_next_window,&lookformax,
  1570. &lastmaxamp,&lastmaxampchan,&lastmaxampchanfrq,&lastminamp,&lastminampchan,&lastminampchanfrq,win_peakchan,dz->bigfbuf,dz);
  1571. if(peakcnt > 0) {
  1572. if(ODD(peakcnt)) /* final trough not recorded in peak data... i.e. window was still falling in amp at top of data */
  1573. win_peakchan[peakcnt++] = dz->clength; /* put final trough in final channel */
  1574. /* LOCATE CENTRE FRQ AND (CENTRAL-WINDOW) AMPLITUDE OF EACH PEAK --> arrays 'win_peakamp' and 'win_peakfrq' */
  1575. /* peakcnt gets count of actual peaks, rather than count of peaks+troughs as before */
  1576. peakcnt = locate_pitch_centre_of_each_peak(peakcnt,win_peakchan,win_peakamp,win_peakfrq,botfrq,
  1577. intv_errorbnd,intv_to_top_of_window,intv_to_centre_of_window,intv_to_next_window,dz->bigfbuf,dz);
  1578. /* KEEP ONLY THE LOUDEST PEAKS */
  1579. while(peakcnt > dz->iparam[FE_PKCNT]) { /* If too many peaks */
  1580. minpkpos = 0;
  1581. for(k = 1;k<peakcnt;k++) { /* find position of quietest */
  1582. if(win_peakamp[k] < win_peakamp[minpkpos])
  1583. minpkpos = k;
  1584. }
  1585. peakcnt--; /* eliminate either by dropping off end of list */
  1586. if(minpkpos < peakcnt) { /* or by shuffling later values down over it */
  1587. for(k = minpkpos;k < peakcnt;k++) {
  1588. win_peakamp[k] = win_peakamp[k+1];
  1589. win_peakfrq[k] = win_peakfrq[k+1];
  1590. }
  1591. }
  1592. }
  1593. }
  1594. /* Output number of peaks, peakfrqs; then entire window data */
  1595. fprintf(stdout,"%d\n",peakcnt);
  1596. for(wc = 0; wc < peakcnt;wc++)
  1597. fprintf(stdout,"%lf\n",win_peakfrq[wc]);
  1598. maxamp = 0.0;
  1599. for(cc = 0, vc= 0; cc < dz->clength;cc++,vc+=2)
  1600. maxamp = max(maxamp,dz->bigfbuf[AMPP]); /* find max amp value, for normalisation */
  1601. if(maxamp <= 0.0) {
  1602. for(cc = 0, vc= 0; cc < dz->clength;cc++,vc+=2)
  1603. fprintf(stdout,"%lf\n",0.0);
  1604. } else {
  1605. for(cc = 0, vc= 0; cc < dz->clength;cc++,vc+=2)
  1606. fprintf(stdout,"%lf\n",dz->bigfbuf[AMPP]/maxamp);
  1607. }
  1608. fflush(stdout);
  1609. return(FINISHED);
  1610. }
  1611. wc = 0;
  1612. while(dz->samps_left > 0) {
  1613. if((dz->ssampsread = fgetfbufEx(dz->bigfbuf,dz->buflen,dz->ifd[0],0)) < 0) {
  1614. sprintf(errstr,"Can't read samples from input soundfile\n");
  1615. return(SYSTEM_ERROR);
  1616. }
  1617. dz->samps_left -= dz->ssampsread;
  1618. dz->total_samps_read += dz->ssampsread;
  1619. wins_in_buf = dz->ssampsread / dz->wanted;
  1620. dz->flbufptr[0] = dz->bigfbuf;
  1621. for(n=0;n<wins_in_buf;n++) {
  1622. lastminamp = HUGE; /* forces 1st minamp value to be less than previous minamp position */
  1623. lastminampchan = 0;
  1624. lastmaxampchanfrq = -(dz->nyquist); /* forces first minampchanfrq to be greater than lastmaxampchanfrq */
  1625. lastmaxamp = -HUGE; /* forces 1st maxamp value to be greater than previous maxamp position */
  1626. lastmaxampchan = -1;
  1627. lastminampchanfrq = -(dz->nyquist); /* forces first maxampchanfrq to be greater than lastminampchanfrq */
  1628. lookformax = 1; /* always begin by searching for a maximum (lastmaxamp set to -HUGE) */
  1629. peakcnt = 0; /* initialise peak counter */
  1630. #ifdef EQUALFRQ
  1631. botfrq = dz->param[FE_LOFRQ] - intv_to_centre_of_window; /* initialise bottom frq of 1st peak-window to search */
  1632. #else
  1633. botfrq = dz->param[FE_LOFRQ] / intv_to_centre_of_window; /* initialise bottom frq of 1st peak-window to search */
  1634. #endif
  1635. /* FIND ALL THE PEAKS IN THE WINDOW --> array of peak trof [peak trof ......] in 'win_peakchan' */
  1636. if(dz->vflag[FE_SORTBUF])
  1637. frqsort_buf(dz->flbufptr[0],dz);
  1638. peakcnt = peaks_in_window(botfrq,intv_to_bot_of_srch,intv_to_top_of_srch,intv_to_centre_of_window,intv_to_top_of_window,intv_to_next_window,&lookformax,
  1639. &lastmaxamp,&lastmaxampchan,&lastmaxampchanfrq,&lastminamp,&lastminampchan,&lastminampchanfrq,win_peakchan,dz->flbufptr[0],dz);
  1640. if(peakcnt == 0) {
  1641. dz->flbufptr[0] += dz->wanted;
  1642. if(dz->mode == FE_WINDOWS) {
  1643. ampsum = 0.0;
  1644. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc+=2)
  1645. ampsum += dz->flbufptr[0][AMPP];
  1646. totamp[wc] = (float)ampsum;
  1647. }
  1648. wc++;
  1649. continue; /* peakamp[wc]/peakfrq[wc] retain initial (0,0) vals = a no-peaks window */
  1650. }
  1651. if(ODD(peakcnt)) /* final trough not recorded in peak data... i.e. window was still falling in amp at top of data */
  1652. win_peakchan[peakcnt++] = dz->clength; /* put final trough in final channel */
  1653. /* LOCATE CENTRE FRQ AND (CENTRAL-WINDOW) AMPLITUDE OF EACH PEAK --> arrays 'win_peakamp' and 'win_peakfrq' */
  1654. /* peakcnt gets count of actual peaks, rather than count of peaks+troughs as before */
  1655. peakcnt = locate_pitch_centre_of_each_peak(peakcnt,win_peakchan,win_peakamp,win_peakfrq,botfrq,
  1656. intv_errorbnd,intv_to_top_of_window,intv_to_centre_of_window,intv_to_next_window,dz->flbufptr[0],dz);
  1657. /* ELIMINATE PEAKS AT LOWER SEARCH BOUNDARY */
  1658. for(k = 0;k<peakcnt;k++) {
  1659. if(win_peakfrq[k] < dz->param[FE_LOFRQ] + FLTERR)
  1660. minpkpos = k;
  1661. peakcnt--; /* eliminate either by dropping off end of list */
  1662. if(minpkpos < peakcnt) { /* or by shuffling later values down over it */
  1663. for(k = minpkpos;k < peakcnt;k++) {
  1664. win_peakamp[k] = win_peakamp[k+1];
  1665. win_peakfrq[k] = win_peakfrq[k+1];
  1666. }
  1667. }
  1668. }
  1669. /* KEEP ONLY THE LOUDEST PEAKS */
  1670. while(peakcnt > dz->iparam[FE_PKCNT]) { /* If too many peaks */
  1671. minpkpos = 0;
  1672. for(k = 1;k<peakcnt;k++) { /* find position of quietest */
  1673. if(win_peakamp[k] < win_peakamp[minpkpos])
  1674. minpkpos = k;
  1675. }
  1676. peakcnt--; /* eliminate either by dropping off end of list */
  1677. if(minpkpos < peakcnt) { /* or by shuffling later values down over it */
  1678. for(k = minpkpos;k < peakcnt;k++) {
  1679. win_peakamp[k] = win_peakamp[k+1];
  1680. win_peakfrq[k] = win_peakfrq[k+1];
  1681. }
  1682. }
  1683. }
  1684. /* STORE PEAK DATA IN FEATURES ARRAY -- if peakcnt < dz->iparam[FE_PKCNT0, features array retains dummy vals 0.0 */
  1685. for(k = 0;k < peakcnt; k++) {
  1686. peakamp[wc][k] = win_peakamp[k];
  1687. peakfrq[wc][k] = win_peakfrq[k];
  1688. }
  1689. if(dz->mode == FE_WINDOWS) {
  1690. ampsum = 0.0;
  1691. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc+=2)
  1692. ampsum += dz->flbufptr[0][AMPP];
  1693. totamp[wc] = (float)ampsum;
  1694. }
  1695. dz->flbufptr[0] += dz->wanted;
  1696. wc++;
  1697. }
  1698. }
  1699. switch(dz->mode) {
  1700. case(FE_BEST):
  1701. case(FE_EVERY):
  1702. case(FE_ENVEL):
  1703. /* NOT WRITTEN YET */
  1704. break;
  1705. case(FE_WINDOWS):
  1706. /* Output number of peaks, number of windows, minfrq, maxfrq; then time, (normalised) amp, frq data in triples */
  1707. startwin = dz->iparam[FE_WINTIME];
  1708. endwin = min(startwin + dz->iparam[FE_WINCNT],dz->wlength);
  1709. fprintf(stdout,"%d %d\n",dz->iparam[FE_PKCNT],dz->iparam[FE_WINCNT]);
  1710. fprintf(stdout,"%lf %lf\n",dz->param[FE_LOFRQ],dz->param[FE_HIFRQ]);
  1711. fprintf(stdout,"%lf %lf\n",startwin * dz->frametime,endwin * dz->frametime);
  1712. OK = 0;
  1713. for(wc = startwin; wc < endwin; wc++) {
  1714. if(totamp[wc] > MIN_DB) {
  1715. OK = 1;
  1716. break;
  1717. }
  1718. }
  1719. if (!OK) {
  1720. sprintf(errstr,"NO SIGNIFICANT SIGNAL-LEVEL FOUND");
  1721. return(DATA_ERROR);
  1722. }
  1723. for(wc = startwin; wc < endwin; wc++)
  1724. fprintf(stdout,"%f\n",totamp[wc]);
  1725. maxamp = 0.0;
  1726. for(wc = startwin; wc < endwin;wc++) {
  1727. for(k=0;k<dz->iparam[FE_PKCNT];k++)
  1728. maxamp = max(maxamp,peakamp[wc][k]); /* find max amp value, for normalisation */
  1729. }
  1730. if(maxamp <= 0.0) {
  1731. for(wc = startwin; wc < endwin;wc++) {
  1732. for(k=0;k<dz->iparam[FE_PKCNT];k++) {
  1733. fprintf(stdout,"%lf %lf %lf\n",wc * dz->frametime,peakfrq[wc][k],0.0);
  1734. }
  1735. }
  1736. } else {
  1737. for(wc = startwin; wc < endwin;wc++) {
  1738. for(k=0;k<dz->iparam[FE_PKCNT];k++) {
  1739. fprintf(stdout,"%lf %lf %lf\n",wc * dz->frametime,peakfrq[wc][k],peakamp[wc][k]/maxamp);
  1740. }
  1741. }
  1742. }
  1743. fflush(stdout);
  1744. break;
  1745. case(FE_AVERAGE):
  1746. #ifndef EQUALFRQ
  1747. minmidi = unchecked_hztomidi(dz->param[FE_LOFRQ]);
  1748. #endif
  1749. startwin = dz->iparam[FE_START];
  1750. endwin = dz->iparam[FE_END];
  1751. peakcnt = (int)ceil(interval/dz->param[FE_STEP]); /* no of possible peak values */
  1752. for(wc = startwin; wc < endwin;wc++) {
  1753. for(k = 0;k < dz->iparam[FE_PKCNT]; k++) {
  1754. if(peakfrq[wc][k] > 0.0) {
  1755. #ifdef EQUALFRQ
  1756. j = (int)floor((peakfrq[wc][k] - dz->param[FE_LOFRQ])/dz->param[FE_STEP]);
  1757. #else
  1758. j = (int)floor((unchecked_hztomidi(peakfrq[wc][k]) - minmidi)/dz->param[FE_STEP]);
  1759. #endif
  1760. peakstats[j]++;
  1761. }
  1762. }
  1763. }
  1764. maxamp = 0.0;
  1765. for(k = 0;k < peakcnt; k++) {
  1766. maxamp = max(maxamp,(double)peakstats[k]); /* find max stats value, for normalisation */
  1767. }
  1768. /* Output minfrq, maxfrq; then "amp", frq data in pairs */
  1769. fprintf(stdout,"%lf %lf\n",dz->param[FE_LOFRQ],dz->param[FE_HIFRQ]);
  1770. #ifdef EQUALFRQ
  1771. thisval = dz->param[FE_LOFRQ];
  1772. #else
  1773. thisval = minmidi;
  1774. #endif
  1775. if(maxamp <= 0.0) {
  1776. for(k = 0;k < peakcnt; k++) {
  1777. #ifdef EQUALFRQ
  1778. fprintf(stdout,"%lf %lf\n",thisval,(double)0.0);
  1779. #else
  1780. fprintf(stdout,"%lf %lf\n",miditohz(thisval),(double)0.0);
  1781. #endif
  1782. thisval += dz->param[FE_STEP];
  1783. }
  1784. } else {
  1785. for(k = 0;k < peakcnt; k++) {
  1786. #ifdef EQUALFRQ
  1787. fprintf(stdout,"%lf %lf\n",thisval,(double)peakstats[k]/maxamp);
  1788. #else
  1789. fprintf(stdout,"%lf %lf\n",miditohz(thisval),(double)peakstats[k]/maxamp);
  1790. #endif
  1791. thisval += dz->param[FE_STEP];
  1792. }
  1793. }
  1794. fflush(stdout);
  1795. break;
  1796. }
  1797. return(FINISHED);
  1798. }
  1799. /********************************************** PEAKS_IN_WINDOW **************************************************
  1800. *
  1801. * Scan an analysis window to find alternate peaks and troughs.
  1802. */
  1803. int peaks_in_window(double botfrq,double intv_to_bot_of_srch,double intv_to_top_of_srch,double intv_to_centre_of_window,double intv_to_top_of_window,
  1804. double intv_to_next_window,int *lookformax,double *lastmaxamp,int *lastmaxampchan,double *lastmaxampchanfrq,
  1805. double *lastminamp,int *lastminampchan,double *lastminampchanfrq,int *win_peakchan,float *buf,dataptr dz)
  1806. {
  1807. /* TEST *
  1808. static int gocnt = 0;
  1809. int gocnt2 = 0;
  1810. * TEST */
  1811. double srchtopfrq, srchbotfrq, topfrq, minamp, maxamp, maxampchanfrq=0.0, minampchanfrq=0.0;
  1812. int srchbotchan, srchtopchan, founddata, cc, vc, maxampchan=0, minampchan=0, peakcnt;
  1813. peakcnt = 0;
  1814. /* SET UP SEARCH WINDOWS TO LOOK FOR AMPLITUDE PEAKS AND TROUGHS */
  1815. #ifdef EQUALFRQ
  1816. while((srchtopfrq = botfrq + intv_to_top_of_srch) < dz->nyquist) { /* set frq corresponding to top channel of search-window */
  1817. //centrefrq = botfrq + intv_to_centre_of_window; /* set centrefrq of actual-window */
  1818. topfrq = botfrq + intv_to_top_of_window; /* set topfrq of actual-window of search */
  1819. if((srchbotfrq = botfrq + intv_to_bot_of_srch) <= dz->halfchwidth) /* set frq corresponding to bottom channel of search-window */
  1820. #else
  1821. while((srchtopfrq = botfrq * intv_to_top_of_srch) < dz->nyquist) { /* set frq corresponding to top channel of search-window */
  1822. centrefrq = botfrq * intv_to_centre_of_window; /* set centrefrq of actual-window */
  1823. topfrq = botfrq * intv_to_top_of_window; /* set topfrq of actual-window of search */
  1824. if((srchbotfrq = botfrq * intv_to_bot_of_srch) <= dz->halfchwidth) /* set frq corresponding to bottom channel of search-window */
  1825. #endif
  1826. srchbotfrq = dz->halfchwidth + FLTERR;
  1827. if(srchtopfrq > dz->param[FE_HIFRQ])
  1828. break;
  1829. srchbotchan = (int)round(srchbotfrq/dz->chwidth); /* set bot and top chans of search-window */
  1830. srchtopchan = (int)round(srchtopfrq/dz->chwidth);
  1831. minamp = HUGE; /* initialise vals of max and min amp in search-window */
  1832. maxamp = -HUGE;
  1833. founddata = 0;
  1834. /* SEARCH WINDOW FOR AMPLITUDE PEAKS AND TROUGHS */
  1835. for(cc = srchbotchan, vc = cc*2; cc < srchtopchan; cc++,vc+=2) { /* Find max and min amplitudes in search-window */
  1836. if(buf[FREQ] >= botfrq && buf[FREQ] <= topfrq) { /* considering only channel data whose frq lies within actual-window limits */
  1837. founddata = 1;
  1838. if(buf[AMPP] > maxamp) {
  1839. maxamp = buf[AMPP];
  1840. maxampchan = cc;
  1841. maxampchanfrq = buf[FREQ];
  1842. }
  1843. if(buf[AMPP] < minamp) {
  1844. minamp = buf[AMPP];
  1845. minampchan = cc;
  1846. minampchanfrq = buf[FREQ];
  1847. }
  1848. }
  1849. }
  1850. if(!founddata) {
  1851. #ifdef EQUALFRQ
  1852. botfrq += intv_to_next_window;
  1853. #else
  1854. botfrq *= intv_to_next_window;
  1855. #endif
  1856. continue;
  1857. }
  1858. /* COMPARE SUCCESIVE WINDOWS FOR TRUE PEAKS AND TROUGHS */
  1859. if(*lookformax) { /* If searching for a maximum */
  1860. if(maxamp < *lastmaxamp) { /* If we've passed the local maximum */
  1861. *lookformax = 0; /* switch to looking for a trough */
  1862. win_peakchan[(peakcnt)++] = *lastmaxampchan; /* store the location of the peak */
  1863. if(minampchanfrq > *lastmaxampchanfrq) { /* if we already have a minamp AFTER the maxamp chan */
  1864. *lastminamp = minamp; /* initialise search for trough at trough so far */
  1865. *lastminampchan = minampchan;
  1866. *lastminampchanfrq = minampchanfrq;
  1867. } else { /* else */
  1868. *lastminamp = HUGE; /* initialise search for trough: forces a lastminamp to be set at BETA */
  1869. }
  1870. *lastmaxamp = -HUGE; /* reinitialise the local maximum: */
  1871. /* forces a lastmaxamp to be set at ALPHA next time lookformax = 1 */
  1872. } else { /* if we've not passed the local maximum */ /* ALPHA */
  1873. *lastmaxamp = maxamp; /* remember the current maximum */
  1874. *lastmaxampchan = maxampchan;
  1875. *lastmaxampchanfrq = maxampchanfrq;
  1876. }
  1877. } else {
  1878. if(minamp > *lastminamp) { /* If we've passed the local trough */
  1879. *lookformax = 1; /* switch to looking for a peak */
  1880. win_peakchan[(peakcnt)++] = *lastminampchan; /* store the location of the trough */
  1881. if(maxampchanfrq > *lastminampchanfrq) { /* if we already have a maxamp AFTER the minamp chan */
  1882. *lastmaxamp = maxamp; /* initialise search for trough at trough so far */
  1883. *lastmaxampchan = maxampchan;
  1884. *lastmaxampchanfrq = maxampchanfrq;
  1885. } else { /* else */
  1886. *lastmaxamp = -HUGE; /* initialise search for peak: forces a lastmaxamp to be set at ALPHA */
  1887. }
  1888. *lastminamp = HUGE; /* reinitialise the local minimum */
  1889. /* forces a lastminamp to be set at BETA next time lookformax = 0 */
  1890. } else { /* if we've not passed the local maximum */ /* BETA */
  1891. *lastminamp = minamp; /* remember the current maximum */
  1892. *lastminampchan = minampchan;
  1893. *lastminampchanfrq = minampchanfrq;
  1894. }
  1895. }
  1896. #ifdef EQUALFRQ
  1897. botfrq += intv_to_next_window;
  1898. #else
  1899. botfrq *= intv_to_next_window;
  1900. #endif
  1901. }
  1902. /* TEST *
  1903. gocnt++;
  1904. * TEST */
  1905. return peakcnt;
  1906. }
  1907. int locate_pitch_centre_of_each_peak(int peakandtrofcnt,int *win_peakchan,float *win_peakamp,float *win_peakfrq,double footfrq,
  1908. double intv_errorbnd,double intv_to_top_of_window,double intv_to_centre_of_window,double intv_to_next_window,
  1909. float *buf,dataptr dz)
  1910. {
  1911. int k, cc, vc, actual_peakcnt, gotdata;
  1912. double pktopfrq, pkbotfrq; /* frqs at top and bottom of peak */
  1913. double botfrq, centrefrq, topfrq; /* frqs at top and bottom of scanning-window in peak */
  1914. double srchbotfrq, srchtopfrq; /* frqs corresponding to channels at outer search-edges of scanning-window in peak */
  1915. double peakampsum, ampsum;
  1916. int srchbotchan, srchtopchan;
  1917. k = 1; /* set k to location of 1st trough in data */
  1918. actual_peakcnt = 0;
  1919. pkbotfrq = footfrq;
  1920. while(k < peakandtrofcnt) {
  1921. /* SET UP PEAK-PARAMETERS */
  1922. pktopfrq = win_peakchan[k] * dz->chwidth; /* trough at top edge of peak */
  1923. #ifdef EQUALFRQ
  1924. centrefrq = (pktopfrq + pkbotfrq)/2.0;
  1925. #else
  1926. centrefrq = (unchecked_hztomidi(pktopfrq) + unchecked_hztomidi(pkbotfrq))/2.0;
  1927. centrefrq = miditohz(centrefrq); /* default the peak centrefrq to pitch-midway between troughs */
  1928. #endif
  1929. /* SET UP PEAK-SCANNING WINDOW */
  1930. botfrq = pkbotfrq;
  1931. #ifdef EQUALFRQ
  1932. topfrq = botfrq + intv_to_top_of_window;
  1933. #else
  1934. topfrq = botfrq * intv_to_top_of_window;
  1935. #endif
  1936. peakampsum = -HUGE;
  1937. gotdata = 0;
  1938. /* MOVE PEAK-SCANNING WINDOW ACROSS PEAK TO FIND PITCH-POSITION OF MAXIMUM LEVEL */
  1939. while(topfrq <= pktopfrq) {
  1940. srchbotfrq = max((botfrq / intv_errorbnd),dz->halfchwidth + FLTERR);
  1941. srchtopfrq = min((topfrq * intv_errorbnd),dz->nyquist - FLTERR);
  1942. srchbotchan = (int)round(srchbotfrq/dz->chwidth); /* set bot and top chans of search-window */
  1943. srchtopchan = (int)round(srchtopfrq/dz->chwidth); /* set bot and top chans of search-window */
  1944. ampsum = 0.0;
  1945. for(cc=srchbotchan,vc = cc*2;cc<= srchtopchan;cc++,vc+=2) {
  1946. if(buf[FREQ] >= botfrq && buf[FREQ] <= topfrq) { /* sum the amplitude over the scanning-window */
  1947. gotdata = 1;
  1948. ampsum += buf[AMPP];
  1949. }
  1950. }
  1951. if(ampsum > peakampsum) { /* find the location of loudest scanning-window */
  1952. peakampsum = ampsum;
  1953. #ifdef EQUALFRQ
  1954. centrefrq = botfrq + intv_to_centre_of_window;
  1955. #else
  1956. centrefrq = botfrq * intv_to_centre_of_window;
  1957. #endif
  1958. }
  1959. #ifdef EQUALFRQ
  1960. botfrq += intv_to_next_window;
  1961. topfrq = botfrq + intv_to_top_of_window;
  1962. #else
  1963. botfrq *= intv_to_next_window;
  1964. topfrq = botfrq * intv_to_top_of_window;
  1965. #endif
  1966. }
  1967. if(!gotdata) {
  1968. peakampsum = 0.0;
  1969. }
  1970. win_peakamp[actual_peakcnt] = (float)peakampsum; /* store loudest scanning-window-amplitude and centre-frq of peak */
  1971. win_peakfrq[actual_peakcnt] = (float)centrefrq;
  1972. actual_peakcnt++; /* count peaks (only) */
  1973. /* MOVE TO NEXT PEAK */
  1974. pkbotfrq = pktopfrq;
  1975. k += 2;
  1976. }
  1977. return actual_peakcnt;
  1978. }
  1979. double semit_to_ratio(double val)
  1980. {
  1981. val = val/SEMITONES_PER_OCTAVE;
  1982. val = pow(2.0,val);
  1983. return val;
  1984. }
  1985. void frqsort_buf(float *buf,dataptr dz)
  1986. {
  1987. int ccone, ampone, frqone, cctwo, amptwo, frqtwo;
  1988. int lowtop = dz->clength - 1;
  1989. float temp;
  1990. for(ccone = 0,ampone = 0; ccone < lowtop; ccone++,ampone+=2) {
  1991. frqone = ampone + 1;
  1992. for(cctwo = ccone+1,amptwo=cctwo*2; cctwo < dz->clength; cctwo++,amptwo+=2) {
  1993. frqtwo = amptwo+1;
  1994. if(buf[frqtwo] < buf[frqone]) {
  1995. temp = buf[frqone];
  1996. buf[frqone] = buf[frqtwo];
  1997. buf[frqtwo] = temp;
  1998. temp = buf[ampone];
  1999. buf[ampone] = buf[amptwo];
  2000. buf[amptwo] = temp;
  2001. }
  2002. }
  2003. }
  2004. }
  2005. #if 0
  2006. void tellme(char *str) {
  2007. fprintf(stdout,"INFO: %s\n",str);
  2008. fflush(stdout);
  2009. }
  2010. float amp_to_db(double amp, double silence)
  2011. {
  2012. if(amp <= silence)
  2013. return (float)MIN_DB;
  2014. amp = log10(amp) * 20.0;
  2015. return (float)amp;
  2016. }
  2017. #endif