sethares.c 79 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955
  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. /*
  22. * PROCESS TO EXTRACT PEAKS IN SPECTRUM
  23. *
  24. * Based on Bill Sethares idea of using the median as a reference level
  25. * described verbally at CCMIX session in Paris.
  26. *
  27. * M_WINSIZE = parameter for size of peak-search subwindow, in semitones
  28. * M_PEAKING = How much louder than median must a peak be (Range 1 ->)
  29. * M_AMPFLOOR = (relative) level below which peaks are ignored
  30. * M_INTUNE = parameter for in-tune-ness of harmonics, in semitones
  31. * M_LOFRQ = min frq to keep
  32. * M_HIFRQ = max frq to keep
  33. * MODES 0 pitch(amp) data: 1 data in streams: 2 data streamed after statistical check
  34. * dz->vflag[0] = lose the amplitude information
  35. * dz->vflag[1] = mark_zeros, where no peaks found
  36. *
  37. * Output goes to a textfile of
  38. * (1) Time, Pitch and amplitude data OR
  39. * (2) Time and Pitch data only
  40. where ...
  41. * (1) Areas free of peaks may be ignored, or marked with zeros
  42. * (2) Data may be streamed. The number of streams = maximum number peaks found.
  43. * Where there are insufficient peaks in a window to fill all streams,
  44. * (zero amplitude) best-fit virtual frqs are added to the streams for those windows.
  45. * Streaming may be slow, as assiging peaks to streams uses a combinatorial optimisation scheme.
  46. * (3) A statistical survey of the data may be attempted, to extract more streams
  47. * This assumes that the source has a relatively steady spectrum
  48. * Currently NO data reduction.
  49. */
  50. #include <stdio.h>
  51. #include <stdlib.h>
  52. #include <structures.h>
  53. #include <tkglobals.h>
  54. #include <pnames.h>
  55. #include <filetype.h>
  56. #include <processno.h>
  57. #include <modeno.h>
  58. #include <logic.h>
  59. #include <globcon.h>
  60. #include <cdpmain.h>
  61. #include <math.h>
  62. #include <mixxcon.h>
  63. #include <osbind.h>
  64. #include <standalone.h>
  65. #include <speccon.h>
  66. #include <ctype.h>
  67. #include <sfsys.h>
  68. #include <string.h>
  69. #include <srates.h>
  70. //#ifdef unix
  71. #define round(x) lround((x))
  72. //#endif
  73. #ifndef HUGE
  74. #define HUGE 3.40282347e+38F
  75. #endif
  76. char errstr[2400];
  77. int anal_infiles = 1;
  78. int sloom = 0;
  79. int sloombatch = 0;
  80. const char* cdp_version = "7.1.0";
  81. static int check_the_param_validity_and_consistency(dataptr dz);
  82. static int setup_the_application(dataptr dz);
  83. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  84. static int parse_infile_and_check_type(char **cmdline,dataptr dz);
  85. static int setup_the_param_ranges_and_defaults(dataptr dz);
  86. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz);
  87. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  88. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  89. static int establish_application(dataptr dz);
  90. static int initialise_vflags(dataptr dz);
  91. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  92. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  93. static int mark_parameter_types(dataptr dz,aplptr ap);
  94. static int assign_file_data_storage(int infilecnt,dataptr dz);
  95. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  96. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  97. static int get_the_mode_no(char *str, dataptr dz);
  98. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  99. static int allocate_buffer(dataptr dz);
  100. static void displaytime(double time,dataptr dz);
  101. static int is_a_harmonic(double frq1,double frq2,double intune_ratio);
  102. static void eliminate_harmonics(float *peakfrq,float *peakamp,int *len,double intune_ratio);
  103. static void eliminate_duplicated_frqs(float *peakfrq,float *peakamp,int *len);
  104. static void sortfrqs(float *peakfrq,float *peakamp,int len);
  105. static void sortamps(float *medianarray,int * chanarray,int len);
  106. static int locate_peaks_in_subwindow(double lofrq,double hifrq,float *medianarray,int *chanarray,char *peakchan,float * peakfrq,float * peakamp,int peakcnt,dataptr dz);
  107. static int locate_peaks(float *medianarray,int *chanarray,char *peakchan,float *peakfrq,float *peakamp,double frqratio,dataptr dz);
  108. static void combinations(int *combo,int k,int i, int j,int peakcnt,int maxpeakcnt,double *minratiosum,int *instream,
  109. float *peakfrq,float *maxpeakfrq,float *streamfrq,int more);
  110. static void find_best_fit(int *combo,int peakcnt,double *minratiosum,int *instream,float *peakfrq,float *streamfrq);
  111. static int stream_peaks(float *peakfrq,float *peakamp,float *maxpeakfrq,float *lastmaxpeakfrq,float *streamfrq,
  112. int wcnt,int lastmax,int firstmax,int maxpeakcnt,int peakcnt,int *instream,
  113. float *streampeakfrq,float *streampeakamp,dataptr dz);
  114. static int get_next_window_with_max_number_of_peaks(int *peakcnt,int maxpeakcnt,float *lastmaxpeakfrq,float *maxpeakfrq,
  115. int *firstmax,int *lastmax,int wcnt,double frqratio,
  116. int *peaknos,float *medianarray,int *chanarray,char *peakchan,float *peakfrq,float *peakamp,dataptr dz);
  117. static int get_initial_data(float *maxwinamp,int *peakcnt,int *maxpeakcnt,int *firstmax,float *medianarray,int *chanarray,char *peakchan,
  118. float *peakfrq,float *peakamp,int *peaknos,float *maxpeakfrq,float *lastmaxpeakfrq,double frqratio,
  119. int bincnt,float *binlofrq,int *pitchbin,float *bintrof,float *streamfrq,dataptr dz);
  120. static int extract_peaks(dataptr dz);
  121. #define lose_amps dz->vflag[0]
  122. #define as_midi dz->vflag[1]
  123. #define quantised dz->vflag[2]
  124. #define mark_zeros dz->vflag[3]
  125. #define filt_format dz->vflag[4]
  126. /**************************************** MAIN *********************************************/
  127. int main(int argc,char *argv[])
  128. {
  129. int exit_status;
  130. dataptr dz = NULL;
  131. char **cmdline;
  132. int cmdlinecnt;
  133. //aplptr ap;
  134. int is_launched = FALSE;
  135. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  136. fprintf(stdout,"%s\n",cdp_version);
  137. fflush(stdout);
  138. return 0;
  139. }
  140. /* CHECK FOR SOUNDLOOM */
  141. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  142. sloom = 0;
  143. sloombatch = 1;
  144. }
  145. if(sflinit("cdp")){
  146. sfperror("cdp: initialisation\n");
  147. return(FAILED);
  148. }
  149. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  150. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  151. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  152. return(FAILED);
  153. }
  154. if(!sloom) {
  155. if(argc == 1) {
  156. usage1();
  157. return(FAILED);
  158. } else if(argc == 2) {
  159. usage2(argv[1]);
  160. return(FAILED);
  161. }
  162. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  163. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  164. return(FAILED);
  165. }
  166. cmdline = argv;
  167. cmdlinecnt = argc;
  168. if((get_the_process_no(argv[0],dz))<0)
  169. return(FAILED);
  170. cmdline++;
  171. cmdlinecnt--;
  172. dz->maxmode = 4;
  173. if((get_the_mode_no(cmdline[0],dz))<0)
  174. return(FAILED);
  175. cmdline++;
  176. cmdlinecnt--;
  177. if((exit_status = setup_the_application(dz))<0) {
  178. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  179. return(FAILED);
  180. }
  181. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  182. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  183. return(FAILED);
  184. }
  185. } else {
  186. //parse_TK_data() =
  187. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  188. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  189. return(exit_status);
  190. }
  191. }
  192. //ap = dz->application;
  193. // parse_infile_and_hone_type() =
  194. if((exit_status = parse_infile_and_check_type(cmdline,dz))<0) {
  195. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  196. return(FAILED);
  197. }
  198. // setup_param_ranges_and_defaults() =
  199. if((exit_status = setup_the_param_ranges_and_defaults(dz))<0) {
  200. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  201. return(FAILED);
  202. }
  203. // open_first_infile CDP LIB
  204. if((exit_status = open_first_infile(cmdline[0],dz))<0) {
  205. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  206. return(FAILED);
  207. }
  208. cmdlinecnt--;
  209. cmdline++;
  210. // handle_extra_infiles(): redundant
  211. // handle_outfile() =
  212. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,dz))<0) {
  213. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  214. return(FAILED);
  215. }
  216. // handle_formants() redundant
  217. // handle_formant_quiksearch() redundant
  218. // handle_special_data() redundant except
  219. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  220. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  221. return(FAILED);
  222. }
  223. //check_param_validity_and_consistency ....
  224. if((exit_status = check_the_param_validity_and_consistency(dz))<0) {
  225. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  226. return(FAILED);
  227. }
  228. is_launched = TRUE;
  229. //allocate_large_buffers() ... replaced by CDP LIB
  230. dz->extra_bufcnt = 0;
  231. dz->bptrcnt = 1;
  232. if((exit_status = establish_spec_bufptrs_and_extra_buffers(dz))<0) {
  233. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  234. return(FAILED);
  235. }
  236. if((exit_status = allocate_buffer(dz)) < 0) {
  237. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  238. return(FAILED);
  239. }
  240. if((exit_status = extract_peaks(dz))< 0) {
  241. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  242. return(FAILED);
  243. }
  244. if((exit_status = complete_output(dz))<0) { // CDP LIB
  245. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  246. return(FAILED);
  247. }
  248. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  249. free(dz);
  250. return(SUCCEEDED);
  251. }
  252. /**********************************************
  253. REPLACED CDP LIB FUNCTIONS
  254. **********************************************/
  255. /************************ GET_THE_MODE_NO *********************/
  256. int get_the_mode_no(char *str, dataptr dz)
  257. {
  258. if(sscanf(str,"%d",&dz->mode)!=1) {
  259. sprintf(errstr,"Cannot read mode of program.\n");
  260. return(USAGE_ONLY);
  261. }
  262. if(dz->mode <= 0 || dz->mode > dz->maxmode) {
  263. sprintf(errstr,"Program mode value [%d] is out of range [1 - %d].\n",dz->mode,dz->maxmode);
  264. return(USAGE_ONLY);
  265. }
  266. dz->mode--; /* CHANGE TO INTERNAL REPRESENTATION OF MODE NO */
  267. return(FINISHED);
  268. }
  269. /****************************** SET_PARAM_DATA *********************************/
  270. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  271. {
  272. ap->special_data = (char)special_data;
  273. ap->param_cnt = (char)paramcnt;
  274. ap->max_param_cnt = (char)maxparamcnt;
  275. if(ap->max_param_cnt>0) {
  276. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  277. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  278. return(MEMORY_ERROR);
  279. }
  280. strcpy(ap->param_list,paramlist);
  281. }
  282. return(FINISHED);
  283. }
  284. /****************************** SET_VFLGS *********************************/
  285. int set_vflgs
  286. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  287. {
  288. ap->option_cnt = (char) optcnt; /*RWD added cast */
  289. if(optcnt) {
  290. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  291. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  292. return(MEMORY_ERROR);
  293. }
  294. strcpy(ap->option_list,optlist);
  295. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  296. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  297. return(MEMORY_ERROR);
  298. }
  299. strcpy(ap->option_flags,optflags);
  300. }
  301. ap->vflag_cnt = (char) vflagcnt;
  302. ap->variant_param_cnt = (char) vparamcnt;
  303. if(vflagcnt) {
  304. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  305. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  306. return(MEMORY_ERROR);
  307. }
  308. strcpy(ap->variant_list,varlist);
  309. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  310. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  311. return(MEMORY_ERROR);
  312. }
  313. strcpy(ap->variant_flags,varflags);
  314. }
  315. return(FINISHED);
  316. }
  317. /***************************** APPLICATION_INIT **************************/
  318. int application_init(dataptr dz)
  319. {
  320. int exit_status;
  321. int storage_cnt;
  322. int tipc, brkcnt;
  323. aplptr ap = dz->application;
  324. if(ap->vflag_cnt>0)
  325. initialise_vflags(dz);
  326. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  327. ap->total_input_param_cnt = (char)tipc;
  328. if(tipc>0) {
  329. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  330. return(exit_status);
  331. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  332. return(exit_status);
  333. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  334. return(exit_status);
  335. }
  336. brkcnt = tipc;
  337. if(brkcnt>0) {
  338. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  339. return(exit_status);
  340. }
  341. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  342. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  343. return(exit_status);
  344. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  345. return(exit_status);
  346. }
  347. if((exit_status = mark_parameter_types(dz,ap))<0)
  348. return(exit_status);
  349. // establish_infile_constants() replaced by
  350. dz->infilecnt = ONE_NONSND_FILE;
  351. //establish_bufptrs_and_extra_buffers():
  352. return(FINISHED);
  353. }
  354. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  355. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  356. {
  357. int n;
  358. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  359. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  360. return(MEMORY_ERROR);
  361. }
  362. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  363. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  364. return(MEMORY_ERROR);
  365. }
  366. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  367. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  368. return(MEMORY_ERROR);
  369. }
  370. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  371. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  372. return(MEMORY_ERROR);
  373. }
  374. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  375. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  376. return(MEMORY_ERROR);
  377. }
  378. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  379. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  380. return(MEMORY_ERROR);
  381. }
  382. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  383. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  384. return(MEMORY_ERROR);
  385. }
  386. for(n=0;n<brkcnt;n++) {
  387. dz->brk[n] = NULL;
  388. dz->brkptr[n] = NULL;
  389. dz->brkinit[n] = 0;
  390. dz->brksize[n] = 0;
  391. }
  392. return(FINISHED);
  393. }
  394. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  395. /* RWD mallo changed to calloc; helps debug verison run as release! */
  396. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  397. {
  398. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  399. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  400. return(MEMORY_ERROR);
  401. }
  402. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  403. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  404. return(MEMORY_ERROR);
  405. }
  406. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  407. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  408. return(MEMORY_ERROR);
  409. }
  410. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  411. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  412. return(MEMORY_ERROR);
  413. }
  414. return(FINISHED);
  415. }
  416. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  417. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  418. {
  419. int n;
  420. for(n=0;n<storage_cnt;n++) {
  421. dz->is_int[n] = (char)0;
  422. dz->no_brk[n] = (char)0;
  423. }
  424. return(FINISHED);
  425. }
  426. /***************************** MARK_PARAMETER_TYPES **************************/
  427. int mark_parameter_types(dataptr dz,aplptr ap)
  428. {
  429. int n, m; /* PARAMS */
  430. for(n=0;n<ap->max_param_cnt;n++) {
  431. switch(ap->param_list[n]) {
  432. case('0'): break; /* dz->is_active[n] = 0 is default */
  433. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  434. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  435. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  436. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  437. default:
  438. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  439. return(PROGRAM_ERROR);
  440. }
  441. } /* OPTIONS */
  442. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  443. switch(ap->option_list[n]) {
  444. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  445. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  446. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  447. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  448. default:
  449. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  450. return(PROGRAM_ERROR);
  451. }
  452. } /* VARIANTS */
  453. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  454. switch(ap->variant_list[n]) {
  455. case('0'): break;
  456. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  457. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  458. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  459. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  460. default:
  461. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  462. return(PROGRAM_ERROR);
  463. }
  464. } /* INTERNAL */
  465. for(n=0,
  466. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  467. switch(ap->internal_param_list[n]) {
  468. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  469. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  470. case('d'): dz->no_brk[m] = (char)1; break;
  471. default:
  472. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  473. return(PROGRAM_ERROR);
  474. }
  475. }
  476. return(FINISHED);
  477. }
  478. /***************************** HANDLE_THE_OUTFILE **************************/
  479. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz)
  480. {
  481. int exit_status;
  482. char *filename = NULL;
  483. filename = (*cmdline)[0];
  484. strcpy(dz->outfilename,filename);
  485. if((exit_status = create_sized_outfile(filename,dz))<0)
  486. return(exit_status);
  487. (*cmdline)++;
  488. (*cmdlinecnt)--;
  489. return(FINISHED);
  490. }
  491. /***************************** ESTABLISH_APPLICATION **************************/
  492. int establish_application(dataptr dz)
  493. {
  494. aplptr ap;
  495. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  496. sprintf(errstr,"establish_application()\n");
  497. return(MEMORY_ERROR);
  498. }
  499. ap = dz->application;
  500. memset((char *)ap,0,sizeof(struct applic));
  501. return(FINISHED);
  502. }
  503. /************************* INITIALISE_VFLAGS *************************/
  504. int initialise_vflags(dataptr dz)
  505. {
  506. int n;
  507. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  508. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  509. return(MEMORY_ERROR);
  510. }
  511. for(n=0;n<dz->application->vflag_cnt;n++)
  512. dz->vflag[n] = FALSE;
  513. return FINISHED;
  514. }
  515. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  516. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  517. {
  518. int n;
  519. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  520. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  521. return(MEMORY_ERROR);
  522. }
  523. for(n=0;n<tipc;n++)
  524. ap->default_val[n] = 0.0;
  525. return(FINISHED);
  526. }
  527. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  528. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  529. {
  530. int n;
  531. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  532. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  533. return(MEMORY_ERROR);
  534. }
  535. for(n=0;n<tipc;n++)
  536. dz->is_active[n] = (char)0;
  537. return(FINISHED);
  538. }
  539. /************************* SETUP_THE_APPLICATION *******************/
  540. int setup_the_application(dataptr dz)
  541. {
  542. int exit_status;
  543. aplptr ap;
  544. if((exit_status = establish_application(dz))<0) // GLOBAL
  545. return(FAILED);
  546. ap = dz->application;
  547. // SEE parstruct FOR EXPLANATION of next 2 functions
  548. exit_status = set_param_data(ap,0 ,5,5,"ddddd");
  549. if(exit_status <0)
  550. return(FAILED);
  551. switch(dz->mode) {
  552. case(0):
  553. exit_status = set_vflgs(ap,"h",1,"d","amqz",4,0,"0000");
  554. break;
  555. case(1):
  556. case(2):
  557. case(3):
  558. exit_status = set_vflgs(ap,"h",1,"d","amqzf",5,0,"00000");
  559. break;
  560. }
  561. if(exit_status<0)
  562. return(FAILED);
  563. dz->has_otherfile = FALSE;
  564. dz->input_data_type = ANALFILE_ONLY;
  565. dz->process_type = TO_TEXTFILE;
  566. dz->outfiletype = TEXTFILE_OUT;
  567. return application_init(dz); //GLOBAL
  568. }
  569. /************************* PARSE_INFILE_AND_CHECK_TYPE *******************/
  570. int parse_infile_and_check_type(char **cmdline,dataptr dz)
  571. {
  572. int exit_status;
  573. infileptr infile_info;
  574. if(!sloom) {
  575. if((infile_info = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  576. sprintf(errstr,"INSUFFICIENT MEMORY for infile structure to test file data.");
  577. return(MEMORY_ERROR);
  578. } else if((exit_status = cdparse(cmdline[0],infile_info))<0) {
  579. sprintf(errstr,"Failed tp parse input file %s\n",cmdline[0]);
  580. return(PROGRAM_ERROR);
  581. } else if(infile_info->filetype != ANALFILE) {
  582. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  583. return(DATA_ERROR);
  584. } else if((exit_status = copy_parse_info_to_main_structure(infile_info,dz))<0) {
  585. sprintf(errstr,"Failed to copy file parsing information\n");
  586. return(PROGRAM_ERROR);
  587. }
  588. free(infile_info);
  589. }
  590. dz->clength = dz->wanted / 2;
  591. dz->chwidth = dz->nyquist/(double)(dz->clength-1);
  592. dz->halfchwidth = dz->chwidth/2.0;
  593. return(FINISHED);
  594. }
  595. /************************* SETUP_THE_PARAM_RANGES_AND_DEFAULTS *******************/
  596. int setup_the_param_ranges_and_defaults(dataptr dz)
  597. {
  598. int exit_status;
  599. aplptr ap = dz->application;
  600. // set_param_ranges()
  601. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  602. // NB total_input_param_cnt is > 0 !!!s
  603. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  604. return(FAILED);
  605. // get_param_ranges()
  606. ap->lo[0] = 1; // winsize: semitones
  607. ap->hi[0] = 96;
  608. ap->default_val[0] = 12;
  609. ap->lo[1] = 1; // peaking: ratio to median
  610. ap->hi[1] = 1000;
  611. ap->default_val[1] = 1.5;
  612. ap->lo[2] = .0001; // floor: ratio to max window in entire file
  613. ap->hi[2] = 1;
  614. ap->default_val[2] = .001;
  615. ap->lo[3] = dz->chwidth; // min frq to find
  616. ap->hi[3] = dz->nyquist;
  617. ap->default_val[3] = dz->chwidth;
  618. ap->lo[4] = dz->chwidth; // max frq to find
  619. ap->hi[4] = dz->nyquist;
  620. ap->default_val[4] = dz->nyquist;
  621. ap->lo[5] = 0.0; // intunenuess of harmonics, semitones
  622. ap->hi[5] = 6.0;
  623. ap->default_val[5] = 1.0;
  624. dz->maxmode = 4;
  625. if(!sloom)
  626. put_default_vals_in_all_params(dz);
  627. return(FINISHED);
  628. }
  629. /********************************* PARSE_SLOOM_DATA *********************************/
  630. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  631. {
  632. int exit_status;
  633. int cnt = 1, infilecnt;
  634. int filesize, insams, inbrksize;
  635. double dummy;
  636. int true_cnt = 0;
  637. //aplptr ap;
  638. while(cnt<=PRE_CMDLINE_DATACNT) {
  639. if(cnt > argc) {
  640. sprintf(errstr,"Insufficient data sent from TK\n");
  641. return(DATA_ERROR);
  642. }
  643. switch(cnt) {
  644. case(1):
  645. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  646. sprintf(errstr,"Cannot read process no. sent from TK\n");
  647. return(DATA_ERROR);
  648. }
  649. break;
  650. case(2):
  651. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  652. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  653. return(DATA_ERROR);
  654. }
  655. if(dz->mode > 0)
  656. dz->mode--;
  657. //setup_particular_application() =
  658. if((exit_status = setup_the_application(dz))<0)
  659. return(exit_status);
  660. //ap = dz->application;
  661. break;
  662. case(3):
  663. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  664. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  665. return(DATA_ERROR);
  666. }
  667. if(infilecnt < 1) {
  668. true_cnt = cnt + 1;
  669. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  670. }
  671. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  672. return(exit_status);
  673. break;
  674. case(INPUT_FILETYPE+4):
  675. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  676. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  677. return(DATA_ERROR);
  678. }
  679. break;
  680. case(INPUT_FILESIZE+4):
  681. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  682. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  683. return(DATA_ERROR);
  684. }
  685. dz->insams[0] = filesize;
  686. break;
  687. case(INPUT_INSAMS+4):
  688. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  689. sprintf(errstr,"Cannot read insams sent from TK\n");
  690. return(DATA_ERROR);
  691. }
  692. dz->insams[0] = insams;
  693. break;
  694. case(INPUT_SRATE+4):
  695. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  696. sprintf(errstr,"Cannot read srate sent from TK\n");
  697. return(DATA_ERROR);
  698. }
  699. break;
  700. case(INPUT_CHANNELS+4):
  701. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  702. sprintf(errstr,"Cannot read channels sent from TK\n");
  703. return(DATA_ERROR);
  704. }
  705. break;
  706. case(INPUT_STYPE+4):
  707. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  708. sprintf(errstr,"Cannot read stype sent from TK\n");
  709. return(DATA_ERROR);
  710. }
  711. break;
  712. case(INPUT_ORIGSTYPE+4):
  713. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  714. sprintf(errstr,"Cannot read origstype sent from TK\n");
  715. return(DATA_ERROR);
  716. }
  717. break;
  718. case(INPUT_ORIGRATE+4):
  719. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  720. sprintf(errstr,"Cannot read origrate sent from TK\n");
  721. return(DATA_ERROR);
  722. }
  723. break;
  724. case(INPUT_MLEN+4):
  725. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  726. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  727. return(DATA_ERROR);
  728. }
  729. break;
  730. case(INPUT_DFAC+4):
  731. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  732. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  733. return(DATA_ERROR);
  734. }
  735. break;
  736. case(INPUT_ORIGCHANS+4):
  737. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  738. sprintf(errstr,"Cannot read origchans sent from TK\n");
  739. return(DATA_ERROR);
  740. }
  741. break;
  742. case(INPUT_SPECENVCNT+4):
  743. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  744. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  745. return(DATA_ERROR);
  746. }
  747. dz->specenvcnt = dz->infile->specenvcnt;
  748. break;
  749. case(INPUT_WANTED+4):
  750. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  751. sprintf(errstr,"Cannot read wanted sent from TK\n");
  752. return(DATA_ERROR);
  753. }
  754. break;
  755. case(INPUT_WLENGTH+4):
  756. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  757. sprintf(errstr,"Cannot read wlength sent from TK\n");
  758. return(DATA_ERROR);
  759. }
  760. break;
  761. case(INPUT_OUT_CHANS+4):
  762. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  763. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  764. return(DATA_ERROR);
  765. }
  766. break;
  767. /* RWD these chanegs to samps - tk will have to deal with that! */
  768. case(INPUT_DESCRIPTOR_BYTES+4):
  769. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  770. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  771. return(DATA_ERROR);
  772. }
  773. break;
  774. case(INPUT_IS_TRANSPOS+4):
  775. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  776. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  777. return(DATA_ERROR);
  778. }
  779. break;
  780. case(INPUT_COULD_BE_TRANSPOS+4):
  781. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  782. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  783. return(DATA_ERROR);
  784. }
  785. break;
  786. case(INPUT_COULD_BE_PITCH+4):
  787. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  788. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  789. return(DATA_ERROR);
  790. }
  791. break;
  792. case(INPUT_DIFFERENT_SRATES+4):
  793. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  794. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  795. return(DATA_ERROR);
  796. }
  797. break;
  798. case(INPUT_DUPLICATE_SNDS+4):
  799. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  800. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  801. return(DATA_ERROR);
  802. }
  803. break;
  804. case(INPUT_BRKSIZE+4):
  805. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  806. sprintf(errstr,"Cannot read brksize sent from TK\n");
  807. return(DATA_ERROR);
  808. }
  809. if(inbrksize > 0) {
  810. switch(dz->input_data_type) {
  811. case(WORDLIST_ONLY):
  812. break;
  813. case(PITCH_AND_PITCH):
  814. case(PITCH_AND_TRANSPOS):
  815. case(TRANSPOS_AND_TRANSPOS):
  816. dz->tempsize = inbrksize;
  817. break;
  818. case(BRKFILES_ONLY):
  819. case(UNRANGED_BRKFILE_ONLY):
  820. case(DB_BRKFILES_ONLY):
  821. case(ALL_FILES):
  822. case(ANY_NUMBER_OF_ANY_FILES):
  823. if(dz->extrabrkno < 0) {
  824. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  825. return(DATA_ERROR);
  826. }
  827. if(dz->brksize == NULL) {
  828. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  829. return(PROGRAM_ERROR);
  830. }
  831. dz->brksize[dz->extrabrkno] = inbrksize;
  832. break;
  833. default:
  834. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  835. dz->input_data_type);
  836. return(PROGRAM_ERROR);
  837. }
  838. break;
  839. }
  840. break;
  841. case(INPUT_NUMSIZE+4):
  842. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  843. sprintf(errstr,"Cannot read numsize sent from TK\n");
  844. return(DATA_ERROR);
  845. }
  846. break;
  847. case(INPUT_LINECNT+4):
  848. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  849. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  850. return(DATA_ERROR);
  851. }
  852. break;
  853. case(INPUT_ALL_WORDS+4):
  854. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  855. sprintf(errstr,"Cannot read all_words sent from TK\n");
  856. return(DATA_ERROR);
  857. }
  858. break;
  859. case(INPUT_ARATE+4):
  860. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  861. sprintf(errstr,"Cannot read arate sent from TK\n");
  862. return(DATA_ERROR);
  863. }
  864. break;
  865. case(INPUT_FRAMETIME+4):
  866. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  867. sprintf(errstr,"Cannot read frametime sent from TK\n");
  868. return(DATA_ERROR);
  869. }
  870. dz->frametime = (float)dummy;
  871. break;
  872. case(INPUT_WINDOW_SIZE+4):
  873. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  874. sprintf(errstr,"Cannot read window_size sent from TK\n");
  875. return(DATA_ERROR);
  876. }
  877. break;
  878. case(INPUT_NYQUIST+4):
  879. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  880. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  881. return(DATA_ERROR);
  882. }
  883. break;
  884. case(INPUT_DURATION+4):
  885. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  886. sprintf(errstr,"Cannot read duration sent from TK\n");
  887. return(DATA_ERROR);
  888. }
  889. break;
  890. case(INPUT_MINBRK+4):
  891. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  892. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  893. return(DATA_ERROR);
  894. }
  895. break;
  896. case(INPUT_MAXBRK+4):
  897. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  898. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  899. return(DATA_ERROR);
  900. }
  901. break;
  902. case(INPUT_MINNUM+4):
  903. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  904. sprintf(errstr,"Cannot read minnum sent from TK\n");
  905. return(DATA_ERROR);
  906. }
  907. break;
  908. case(INPUT_MAXNUM+4):
  909. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  910. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  911. return(DATA_ERROR);
  912. }
  913. break;
  914. default:
  915. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  916. return(PROGRAM_ERROR);
  917. }
  918. cnt++;
  919. }
  920. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  921. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  922. return(DATA_ERROR);
  923. }
  924. if(true_cnt)
  925. cnt = true_cnt;
  926. *cmdlinecnt = 0;
  927. while(cnt < argc) {
  928. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  929. return(exit_status);
  930. cnt++;
  931. }
  932. return(FINISHED);
  933. }
  934. /********************************* GET_TK_CMDLINE_WORD *********************************/
  935. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  936. {
  937. if(*cmdlinecnt==0) {
  938. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  939. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  940. return(MEMORY_ERROR);
  941. }
  942. } else {
  943. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  944. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  945. return(MEMORY_ERROR);
  946. }
  947. }
  948. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  949. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  950. return(MEMORY_ERROR);
  951. }
  952. strcpy((*cmdline)[*cmdlinecnt],q);
  953. (*cmdlinecnt)++;
  954. return(FINISHED);
  955. }
  956. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  957. int assign_file_data_storage(int infilecnt,dataptr dz)
  958. {
  959. int exit_status;
  960. int no_sndfile_system_files = FALSE;
  961. dz->infilecnt = infilecnt;
  962. if((exit_status = allocate_filespace(dz))<0)
  963. return(exit_status);
  964. if(no_sndfile_system_files)
  965. dz->infilecnt = 0;
  966. return(FINISHED);
  967. }
  968. /************************************ CHECK_THE_PARAM_VALIDITY_AND_CONSISTENCY **************************************/
  969. int check_the_param_validity_and_consistency(dataptr dz)
  970. {
  971. if(dz->param[M_LOFRQ] >= dz->param[M_HIFRQ]) {
  972. sprintf(errstr,"Low frequency limit (%lf) equal to, or greater than high frequency limit (%lf).\n",dz->param[M_LOFRQ],dz->param[M_HIFRQ]);
  973. return(USER_ERROR);
  974. }
  975. if(dz->mode > 1) {
  976. if(filt_format) {
  977. if(mark_zeros) {
  978. mark_zeros = 0;
  979. fprintf(stdout,"WARNING: filter format output overrides marking no-peak areas.\n");
  980. fflush(stdout);
  981. }
  982. }
  983. }
  984. return FINISHED;
  985. }
  986. /************************* redundant functions: to ensure libs compile OK *******************/
  987. int assign_process_logic(dataptr dz)
  988. {
  989. return(FINISHED);
  990. }
  991. void set_legal_infile_structure(dataptr dz)
  992. {}
  993. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  994. {
  995. return(FINISHED);
  996. }
  997. int setup_internal_arrays_and_array_pointers(dataptr dz)
  998. {
  999. return(FINISHED);
  1000. }
  1001. int establish_bufptrs_and_extra_buffers(dataptr dz)
  1002. {
  1003. return(FINISHED);
  1004. }
  1005. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1006. {
  1007. return(FINISHED);
  1008. }
  1009. int read_special_data(char *str,dataptr dz)
  1010. {
  1011. return(FINISHED);
  1012. }
  1013. int inner_loop
  1014. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  1015. {
  1016. return FINISHED;
  1017. }
  1018. /********************************************************************************************/
  1019. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1020. {
  1021. if (!strcmp(prog_identifier_from_cmdline,"extract")) dz->process = SETHARES;
  1022. else {
  1023. sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  1024. return(USAGE_ONLY);
  1025. }
  1026. return(FINISHED);
  1027. }
  1028. /******************************** USAGE1 ********************************/
  1029. int usage1(void)
  1030. {
  1031. usage2("extract");
  1032. return(USAGE_ONLY);
  1033. }
  1034. /******************************** USAGE2 ********************************/
  1035. int usage2(char *str)
  1036. {
  1037. if(!strcmp(str,"extract")) {
  1038. fprintf(stderr,
  1039. "USAGE: peak extract\n"
  1040. "1 analfile outf winsiz peak floor lo hi [-htune] [-a] [-m] [-q] [-z]\n"
  1041. "2-4 analfile outf winsiz peak floor lo hi [-htune] [-a] [-m] [-q] [-z] [-f]\n"
  1042. "\n"
  1043. "MODE 1 Output time and frq:amp for peaks in each window.\n"
  1044. " Number of peaks may vary from window to window.\n"
  1045. "MODE 2 Assign peaks to max number of pitch-streams.\n"
  1046. " Number of streams = max number of peaks found in any of windows.\n"
  1047. " Where windows have too few peaks to fit all these streams,\n"
  1048. " frq vals (at zero amplitude) at the (current) best-fit frq \n"
  1049. " are set in the stream. All peaks will lie in some stream.\n"
  1050. "MODE 3 Assign peaks to most prominent pitch-streams.\n"
  1051. " This mode assumes spectrum is relatively constant.\n"
  1052. " It parses entire file, counting peaks in every semitone interval.\n"
  1053. " Then uses most visited semitones as stream centres.\n"
  1054. " Time-varying pitch(amp) data then assigned to those streams.\n"
  1055. " Peaks may be discarded where insufficient streams available.\n"
  1056. "MODE 4 Find streams as mode 3, then get average pitch + relative amp\n"
  1057. " of each stream. Output does not vary through time.\n"
  1058. "\n"
  1059. "winsiz semitone width of window used to search for peaks in spectrum.\n"
  1060. " (Range 1 - 96)\n"
  1061. "peak To retain as peak, channel amp must be 'peak' times louder than\n"
  1062. " median amp of all channels in window (Range 1 - 1000)\n"
  1063. "floor Peaks must exceed a floor amplitude to be retained (Range 0.0001 - 1).\n"
  1064. " Entered val is multiplied by max channel amp found anywhere in file.\n"
  1065. "lo Minimum frq to accept as a peak (Range analchanwidth - nyquist)\n"
  1066. "hi Maximum frq to accept as a peak (Range analchanwidth - nyquist)\n"
  1067. "tune If non-zero, any peak which is a harmonic of another peak\n"
  1068. " (to within 'tune' semitones accuracy) is discarded (Range 0 - 6).\n"
  1069. " If set to zero, all peaks are retained.\n"
  1070. "-a Lose the amplitude information:\n"
  1071. " If set, amps information discarded.\n"
  1072. "-m Output frq information as midi:\n"
  1073. "-q Output frq quantised to tempered scale (in quarter-tones):\n"
  1074. "-z Mark peak-free segments:\n"
  1075. " start/end of peak-free areas marked by (timed) zeros in output.\n"
  1076. "-f Output in filter varibank format: This flag cancels the -z flag.\n"
  1077. " If -a flag also set, all outputs amps are set to 1.0.\n"
  1078. "\n");
  1079. } else
  1080. fprintf(stdout,"Unknown option '%s'\n",str);
  1081. return(USAGE_ONLY);
  1082. }
  1083. int usage3(char *str1,char *str2)
  1084. {
  1085. fprintf(stderr,"Insufficient parameters on command line.\n");
  1086. return(USAGE_ONLY);
  1087. }
  1088. /**************************** ALLOCATE_BUFFER ******************************/
  1089. int allocate_buffer(dataptr dz)
  1090. {
  1091. dz->buflen = dz->wanted;
  1092. if((dz->bigfbuf = (float*) malloc(dz->buflen * sizeof(float)))==NULL) {
  1093. sprintf(errstr,"INSUFFICIENT MEMORY for sound buffers.\n");
  1094. return(MEMORY_ERROR);
  1095. }
  1096. dz->flbufptr[0] = dz->bigfbuf;
  1097. return(FINISHED);
  1098. }
  1099. /**************************** EXTRACT_PEAKS ******************************/
  1100. int extract_peaks(dataptr dz)
  1101. {
  1102. int exit_status;
  1103. char temp2[20000];
  1104. char temp[20000];
  1105. char *peakchan;
  1106. float *peakfrq, *peakamp, *medianarray;
  1107. int *chanarray, *peaknos, *instream;
  1108. float *maxpeakfrq, *lastmaxpeakfrq, *streamfrq, *streampeakfrq, *streampeakamp, *binlofrq, *bintrof;
  1109. double frqratio, lasttime = 0.0, lastholetime = 0.0, maxamp, ampratio, normaliser;
  1110. int firstmax = 0, lastmax = 0, wcnt, samps_read, *pitchbin, val;
  1111. int maxpeakcnt = -1, peakcnt=0, inhole, k;
  1112. float maxwinamp = 0.0;
  1113. double time;
  1114. int bincnt;
  1115. double frq;
  1116. double *avamp, *avfrq;
  1117. if(dz->param[M_INTUNE] > 0.0)
  1118. dz->param[M_INTUNE] = pow(SEMITONE_INTERVAL,fabs(dz->param[M_INTUNE]));
  1119. dz->total_samps_read = 0;
  1120. frqratio = pow(SEMITONE_INTERVAL,fabs(dz->param[M_WINSIZE]));
  1121. if((peakchan = (char *)malloc(dz->clength * sizeof(char))) == NULL) {
  1122. sprintf(errstr,"Insufficient memory for peakchan arrays.\n");
  1123. return(MEMORY_ERROR);
  1124. }
  1125. if((peakfrq = (float *)malloc(dz->clength * sizeof(float))) == NULL) {
  1126. sprintf(errstr,"Insufficient memory for peak frq arrays.\n");
  1127. return(MEMORY_ERROR);
  1128. }
  1129. if((peakamp = (float *)malloc(dz->clength * sizeof(float))) == NULL) {
  1130. sprintf(errstr,"Insufficient memory for peak amp arrays.\n");
  1131. return(MEMORY_ERROR);
  1132. }
  1133. if((medianarray = (float *)malloc(dz->clength * sizeof(float))) == NULL) {
  1134. sprintf(errstr,"Insufficient memory for meanval arrays.\n");
  1135. return(MEMORY_ERROR);
  1136. }
  1137. if((chanarray = (int *)malloc(dz->clength * sizeof(int))) == NULL) {
  1138. sprintf(errstr,"Insufficient memory for meanchannel arrays.\n");
  1139. return(MEMORY_ERROR);
  1140. }
  1141. if((peaknos = (int *)malloc(dz->wlength * sizeof(int))) == NULL) {
  1142. sprintf(errstr,"Insufficient memory for peakchan arrays.\n");
  1143. return(MEMORY_ERROR);
  1144. }
  1145. if((maxpeakfrq = (float *)malloc(dz->clength * sizeof(float))) == NULL) {
  1146. sprintf(errstr,"Insufficient memory for peak frq arrays.\n");
  1147. return(MEMORY_ERROR);
  1148. }
  1149. if((lastmaxpeakfrq = (float *)malloc(dz->clength * sizeof(float))) == NULL) {
  1150. sprintf(errstr,"Insufficient memory for peak frq arrays.\n");
  1151. return(MEMORY_ERROR);
  1152. }
  1153. if((streamfrq = (float *)malloc(dz->clength * sizeof(float))) == NULL) {
  1154. sprintf(errstr,"Insufficient memory for peak amp arrays.\n");
  1155. return(MEMORY_ERROR);
  1156. }
  1157. if((instream = (int *)malloc(dz->clength * sizeof(int))) == NULL) {
  1158. sprintf(errstr,"Insufficient memory for peak amp arrays.\n");
  1159. return(MEMORY_ERROR);
  1160. }
  1161. if((streampeakfrq = (float *)malloc(dz->clength * sizeof(float))) == NULL) {
  1162. sprintf(errstr,"Insufficient memory for orig peak frq arrays.\n");
  1163. return(MEMORY_ERROR);
  1164. }
  1165. if((streampeakamp = (float *)malloc(dz->clength * sizeof(float))) == NULL) {
  1166. sprintf(errstr,"Insufficient memory for orig peak amp arrays.\n");
  1167. return(MEMORY_ERROR);
  1168. }
  1169. if((avamp = (double *)malloc(dz->clength * sizeof(double))) == NULL) {
  1170. sprintf(errstr,"Insufficient memory for orig peak amp arrays.\n");
  1171. return(MEMORY_ERROR);
  1172. }
  1173. if((avfrq = (double *)malloc(dz->clength * sizeof(double))) == NULL) {
  1174. sprintf(errstr,"Insufficient memory for orig peak amp arrays.\n");
  1175. return(MEMORY_ERROR);
  1176. }
  1177. //range = dz->nyquist/dz->halfchwidth;
  1178. frq = dz->halfchwidth;
  1179. bincnt = 0;
  1180. while(frq <= dz->nyquist) {
  1181. bincnt++;
  1182. frq *= SEMITONE_INTERVAL;
  1183. }
  1184. bincnt++;
  1185. if((binlofrq = (float *)malloc(bincnt * sizeof(float))) == NULL) {
  1186. sprintf(errstr,"Insufficient memory for peakchan arrays.\n");
  1187. return(MEMORY_ERROR);
  1188. }
  1189. if((pitchbin = (int *)malloc(bincnt * sizeof(int))) == NULL) {
  1190. sprintf(errstr,"Insufficient memory for peakchan arrays.\n");
  1191. return(MEMORY_ERROR);
  1192. }
  1193. if((bintrof = (float *)malloc(dz->clength * sizeof(float))) == NULL) {
  1194. sprintf(errstr,"Insufficient memory for peakchan arrays.\n");
  1195. return(MEMORY_ERROR);
  1196. }
  1197. memset((char *)pitchbin,0,bincnt * sizeof(int));
  1198. k = 0;
  1199. binlofrq[k++] = (float)dz->halfchwidth;
  1200. while(k < bincnt) {
  1201. binlofrq[k] = (float)(binlofrq[k-1] * SEMITONE_INTERVAL);
  1202. k++;
  1203. }
  1204. if((exit_status = get_initial_data(&maxwinamp,&peakcnt,&maxpeakcnt,&firstmax,medianarray,chanarray,
  1205. peakchan,peakfrq,peakamp,peaknos,maxpeakfrq,lastmaxpeakfrq,frqratio,bincnt,binlofrq,pitchbin,bintrof,streamfrq,dz))<0)
  1206. return exit_status;
  1207. dz->param[M_AMPFLOOR] *= maxwinamp; // Set ampfloor relative to loudest window found
  1208. normaliser = 1.0/maxwinamp;
  1209. time = 0.0;
  1210. inhole = 0;
  1211. wcnt = 0;
  1212. dz->total_samps_read = 0;
  1213. while((samps_read = fgetfbufEx(dz->bigfbuf,dz->buflen,dz->ifd[0],0)) > 0) {
  1214. peakcnt = locate_peaks(medianarray,chanarray,peakchan,peakfrq,peakamp,frqratio,dz);
  1215. if(dz->mode > 0) {
  1216. if(dz->mode == 1) {
  1217. if(wcnt == firstmax) {
  1218. if((exit_status = get_next_window_with_max_number_of_peaks(&peakcnt,maxpeakcnt,lastmaxpeakfrq,maxpeakfrq,&firstmax,&lastmax,wcnt,frqratio,
  1219. peaknos,medianarray,chanarray,peakchan,peakfrq,peakamp,dz))<0)
  1220. return exit_status;
  1221. }
  1222. }
  1223. if(peakcnt != maxpeakcnt) {
  1224. stream_peaks(peakfrq,peakamp,maxpeakfrq,lastmaxpeakfrq,streamfrq,wcnt,lastmax,firstmax,maxpeakcnt,peakcnt,
  1225. instream,streampeakfrq,streampeakamp,dz);
  1226. peakcnt = maxpeakcnt;
  1227. }
  1228. }
  1229. if((dz->mode == 2) && filt_format) {
  1230. for(k=0;k<peakcnt;k++)
  1231. peakamp[k] = (float)(peakamp[k] * normaliser);
  1232. }
  1233. if(dz->mode == 3) {
  1234. if(peakcnt > 0) {
  1235. for(k=0;k<peakcnt;k++) {
  1236. avfrq[k] += peakfrq[k];
  1237. avamp[k] += peakamp[k];
  1238. }
  1239. }
  1240. } else {
  1241. if(peakcnt > 0) {
  1242. if(mark_zeros && inhole) { // If not interpolating and at end of peakless time-period
  1243. if(!flteq(lasttime,lastholetime))
  1244. sprintf(temp,"%lf\t0 0",lasttime); // Mark end of peakless time, if necessary
  1245. inhole = 0;
  1246. }
  1247. sprintf(temp,"%lf",time); // Write peaks (frq+amp) found at current time
  1248. for(k=0;k<peakcnt;k++) {
  1249. if(quantised || as_midi) {
  1250. peakfrq[k] = (float)unchecked_hztomidi(peakfrq[k]);
  1251. if(quantised) {
  1252. val = (int)round(peakfrq[k] * 2.0);
  1253. peakfrq[k] = (float)((double)val/2.0);
  1254. }
  1255. if(!as_midi)
  1256. peakfrq[k] = (float)miditohz(peakfrq[k]);
  1257. }
  1258. strcat(temp,"\t");
  1259. if(quantised && as_midi)
  1260. sprintf(temp2," %.1lf",peakfrq[k]);
  1261. else
  1262. sprintf(temp2," %lf",peakfrq[k]);
  1263. strcat(temp,temp2);
  1264. if(!lose_amps) { // Print amplitudes, if amps not suppressed
  1265. sprintf(temp2," %lf",peakamp[k]);
  1266. strcat(temp,temp2); // If filter-format and amps suppressed, set amps to 1.0, and print
  1267. } else if((dz->mode > 0) && filt_format) {
  1268. sprintf(temp2," 1.0");
  1269. strcat(temp,temp2);
  1270. }
  1271. }
  1272. if((exit_status = fprintf(dz->fp,"%s\n",temp))<0)
  1273. return exit_status;
  1274. } else if(mark_zeros && !inhole) { // If no peaks found + not interpolating + not already in peakless time-period
  1275. sprintf(temp,"%lf\t0 0",time); // Mark start of peakless-time
  1276. if((exit_status = fprintf(dz->fp,"%s\n",temp))<0)
  1277. return exit_status;
  1278. lastholetime = time;
  1279. inhole = 1;
  1280. }
  1281. }
  1282. lasttime = time;
  1283. time += dz->frametime;
  1284. dz->total_samps_read += samps_read;
  1285. displaytime(time,dz);
  1286. }
  1287. if(samps_read < 0) {
  1288. sprintf(errstr,"Sample Read Failed After %d Samples\n",dz->total_samps_read);
  1289. return(SYSTEM_ERROR);
  1290. }
  1291. if(dz->mode == 3) {
  1292. maxamp = 0.0;
  1293. for(k=0;k<peakcnt;k++) {
  1294. avfrq[k] /= (double)dz->wlength;
  1295. maxamp = max(avamp[k],maxamp);
  1296. }
  1297. if(maxamp <= 0.0) {
  1298. sprintf(errstr,"No significant peak level found.\n");
  1299. return(DATA_ERROR);
  1300. }
  1301. ampratio = 1.0/maxamp;
  1302. if(filt_format) {
  1303. temp2[0] = ENDOFSTR;
  1304. for(k=0;k<peakcnt;k++) {
  1305. if(as_midi || quantised) {
  1306. avfrq[k] = unchecked_hztomidi(avfrq[k]);
  1307. if(quantised) {
  1308. val = (int)round(avfrq[k] * 2.0);
  1309. avfrq[k] = (double)val/2.0;
  1310. }
  1311. if(!as_midi)
  1312. avfrq[k] = miditohz(avfrq[k]);
  1313. }
  1314. if(lose_amps) {
  1315. if(quantised && as_midi)
  1316. sprintf(temp,"\t%.1lf\t1.0",avfrq[k]);
  1317. else
  1318. sprintf(temp,"\t%lf\t1.0",avfrq[k]);
  1319. } else {
  1320. if(quantised && as_midi)
  1321. sprintf(temp,"\t%.1lf\t%lf",avfrq[k],avamp[k] * ampratio);
  1322. else
  1323. sprintf(temp,"\t%lf\t%lf",avfrq[k],avamp[k] * ampratio);
  1324. }
  1325. strcat(temp2,temp);
  1326. }
  1327. sprintf(temp,"0");
  1328. strcat(temp,temp2);
  1329. if((exit_status = fprintf(dz->fp,"%s\n",temp))<0)
  1330. return exit_status;
  1331. sprintf(temp,"1000");
  1332. strcat(temp,temp2);
  1333. if((exit_status = fprintf(dz->fp,"%s\n",temp))<0)
  1334. return exit_status;
  1335. } else {
  1336. for(k=0;k<peakcnt;k++) {
  1337. if(as_midi || quantised) {
  1338. avfrq[k] = unchecked_hztomidi(avfrq[k]);
  1339. if(quantised) {
  1340. val = (int)round(avfrq[k] * 2.0);
  1341. avfrq[k] = (double)val/2.0;
  1342. }
  1343. if(!as_midi)
  1344. avfrq[k] = miditohz(avfrq[k]);
  1345. }
  1346. if(lose_amps) {
  1347. if(quantised && as_midi)
  1348. sprintf(temp,"%.1lf",avfrq[k]);
  1349. else
  1350. sprintf(temp,"%lf",avfrq[k]);
  1351. } else {
  1352. if(quantised && as_midi)
  1353. sprintf(temp,"%.1lf\t%lf",avfrq[k],avamp[k] * ampratio);
  1354. else
  1355. sprintf(temp,"%lf\t%lf",avfrq[k],avamp[k] * ampratio);
  1356. }
  1357. if((exit_status = fprintf(dz->fp,"%s\n",temp))<0)
  1358. return exit_status;
  1359. }
  1360. }
  1361. }
  1362. return(FINISHED);
  1363. }
  1364. /****************************** LOCATE_PEAKS ***********************************
  1365. *
  1366. * Locate peaks in pvoc window
  1367. */
  1368. int locate_peaks(float *medianarray,int *chanarray,char *peakchan,float *peakfrq,float *peakamp,double frqratio,dataptr dz)
  1369. {
  1370. int peakcnt = 0;
  1371. double lofrq = 0.0;
  1372. double hifrq = dz->chwidth;
  1373. double overlap_lofrq, overlap_hifrq;
  1374. memset((char *)peakchan,0,dz->clength * sizeof(char)); // Initialise peakchan array to NO peaks
  1375. while(hifrq < dz->param[M_HIFRQ]) { // Find peaks in (next disjuct) subwindow
  1376. if(lofrq < dz->param[M_LOFRQ]) {
  1377. lofrq = hifrq; // Advance frqs to next disjunct window
  1378. hifrq = lofrq * frqratio;
  1379. continue;
  1380. }
  1381. peakcnt = locate_peaks_in_subwindow (lofrq,hifrq,medianarray,chanarray,peakchan,peakfrq,peakamp,peakcnt,dz);
  1382. overlap_lofrq = ((lofrq + hifrq)/2.0); // Set lofrq for overlapping window
  1383. lofrq = hifrq; // Advance frqs to next disjunct window
  1384. hifrq = lofrq * frqratio;
  1385. overlap_hifrq = ((lofrq + hifrq)/2.0); // Set hifrq for overlapping window
  1386. if(overlap_hifrq < dz->nyquist) // Do peak search in overlapping window
  1387. peakcnt = locate_peaks_in_subwindow (overlap_lofrq,overlap_hifrq,medianarray,chanarray,peakchan,peakfrq,peakamp,peakcnt,dz);
  1388. }
  1389. if(peakcnt > 0) {
  1390. eliminate_duplicated_frqs(peakfrq,peakamp,&peakcnt);
  1391. sortfrqs(peakfrq,peakamp,peakcnt);
  1392. if(dz->param[M_INTUNE] > 0.0)
  1393. eliminate_harmonics(peakfrq,peakamp,&peakcnt,dz->param[M_INTUNE]);
  1394. }
  1395. return peakcnt;
  1396. }
  1397. /**************************** LOCATE_PEAKS_IN_SUBWINDOW *************************
  1398. *
  1399. * Find peak within a frequency-rahe (subwindow) within the analysis-window.
  1400. * As search uses overlapping subwindows, ensure peak is not already stored before storing it.
  1401. */
  1402. int locate_peaks_in_subwindow(double lofrq,double hifrq,float *medianarray,int *chanarray,char *peakchan,float * peakfrq,float * peakamp,int peakcnt,dataptr dz)
  1403. {
  1404. int vc, cc, j, k;
  1405. int medianarraycnt = 0;
  1406. double medianval, peakfloor, minfrq = max(lofrq,dz->halfchwidth); // Eliminate frequencies too close to zero
  1407. for( vc = 0,cc= 0; vc < dz->wanted; vc += 2,cc++) {
  1408. if(dz->flbufptr[0][FREQ] >= minfrq) {
  1409. if (dz->flbufptr[0][FREQ] < hifrq) { // Collect amplitude in all channels within window-range
  1410. medianarray[medianarraycnt] = dz->flbufptr[0][AMPP];
  1411. chanarray[medianarraycnt] = cc;
  1412. medianarraycnt++;
  1413. } else
  1414. break;
  1415. }
  1416. }
  1417. sortamps(medianarray,chanarray,medianarraycnt); // Sort collected amps into ascending order
  1418. j = medianarraycnt/2;
  1419. if(ODD(medianarraycnt)) // Find the median
  1420. medianval = (medianarray[j] + medianarray[j+1])/2.0;
  1421. else
  1422. medianval = medianarray[medianarraycnt/2];
  1423. peakfloor = medianval * dz->param[M_PEAKING]; // Establish min level for a peak "peaking" is >= 1
  1424. if(peakfloor > dz->param[M_AMPFLOOR]) {
  1425. for(k=j; k < medianarraycnt;k++) { // Locate peaks in this window
  1426. if((medianarray[k] >= peakfloor) && (medianarray[k] > dz->param[M_AMPFLOOR])) {
  1427. cc = chanarray[k];
  1428. vc = cc * 2;
  1429. if(!peakchan[cc]) { // If peak is not already marked as being in peak-list
  1430. peakchan[cc] = 1; // Add it to the list
  1431. peakamp[peakcnt] = dz->flbufptr[0][AMPP];
  1432. peakfrq[peakcnt] = dz->flbufptr[0][FREQ];
  1433. peakcnt++;
  1434. }
  1435. }
  1436. // k++;
  1437. }
  1438. }
  1439. return peakcnt;
  1440. }
  1441. /****************************** SORTAMPS ***********************************
  1442. *
  1443. * Sort channel amplitudes into ascending order, in order to find median
  1444. */
  1445. void sortamps(float *medianarray,int * chanarray,int len)
  1446. {
  1447. int m, n, chan;
  1448. float temp;
  1449. if(len<=1)
  1450. return;
  1451. for(n = 0;n < len-1;n++) {
  1452. m = n+1;
  1453. while(m < len) {
  1454. if(medianarray[n] > medianarray[m]) {
  1455. temp = medianarray[n];
  1456. medianarray[n] = medianarray[m];
  1457. medianarray[m] = temp;
  1458. chan = chanarray[n];
  1459. chanarray[n] = chanarray[m];
  1460. chanarray[m] = chan;
  1461. }
  1462. m++;
  1463. }
  1464. }
  1465. }
  1466. /****************************** SORTFRQS ***********************************
  1467. *
  1468. * Sort peak frequencies into ascending order
  1469. */
  1470. void sortfrqs(float *peakfrq,float *peakamp,int len)
  1471. {
  1472. int m, n;
  1473. float temp;
  1474. if(len<=1)
  1475. return;
  1476. for(n = 0;n < len-1;n++) {
  1477. m = n+1;
  1478. while(m < len) {
  1479. if(peakfrq[n] > peakfrq[m]) {
  1480. temp = peakfrq[n];
  1481. peakfrq[n] = peakfrq[m];
  1482. peakfrq[m] = temp;
  1483. temp = peakamp[n];
  1484. peakamp[n] = peakamp[m];
  1485. peakamp[m] = temp;
  1486. }
  1487. m++;
  1488. }
  1489. }
  1490. }
  1491. /****************************** ELIMINATE_DUPLICATED_FRQS ***********************************/
  1492. void eliminate_duplicated_frqs(float *peakfrq,float *peakamp,int *len)
  1493. {
  1494. int m, n, j, len_less_one;
  1495. if(*len<=1)
  1496. return;
  1497. len_less_one = *len - 1;
  1498. for(n = 0;n < len_less_one;n++) {
  1499. m = n+1;
  1500. while(m < *len) {
  1501. if(flteq(peakfrq[n],peakfrq[m])) {
  1502. peakamp[n] = max(peakamp[n],peakamp[m]); // Keep loudest peak channel
  1503. j = m+1;
  1504. while(j < *len) { // Eliminate duplicated peak, by shuflback
  1505. peakfrq[j-1] = peakfrq[j];
  1506. peakamp[j-1] = peakamp[j];
  1507. j++;
  1508. }
  1509. (*len)--;
  1510. len_less_one--;
  1511. } else
  1512. m++;
  1513. }
  1514. // n++;
  1515. }
  1516. }
  1517. /****************************** ELIMINATE_HARMONICS ***********************************/
  1518. void eliminate_harmonics(float *peakfrq,float *peakamp,int *len,double intune_ratio)
  1519. {
  1520. int m, n, j, len_less_one;
  1521. if(*len<=1)
  1522. return;
  1523. len_less_one = *len - 1;
  1524. for(n = 0;n < len_less_one;n++) {
  1525. m = n+1;
  1526. while(m < *len) {
  1527. if(is_a_harmonic(peakfrq[m],peakfrq[n],intune_ratio)) {
  1528. j = m+1;
  1529. while(j < *len) { // Eliminate harmonic, by shuflback
  1530. peakfrq[j-1] = peakfrq[j];
  1531. peakamp[j-1] = peakamp[j];
  1532. j++;
  1533. }
  1534. (*len)--;
  1535. len_less_one--;
  1536. } else
  1537. m++;
  1538. }
  1539. }
  1540. }
  1541. /**************************** IS_A_HARMONIC *************************/
  1542. int is_a_harmonic(double frq1,double frq2,double intune_ratio)
  1543. {
  1544. double ratio;
  1545. int iratio;
  1546. double intvl;
  1547. ratio = frq1/frq2;
  1548. iratio = round(ratio);
  1549. if(ratio > iratio)
  1550. intvl = ratio/(double)iratio;
  1551. else
  1552. intvl = (double)iratio/ratio;
  1553. if(intvl > intune_ratio)
  1554. return(FALSE);
  1555. return(TRUE);
  1556. }
  1557. /**************************** STREAM_PEAKS *************************
  1558. *
  1559. * If there are LESS peaks Than there are peak-streams.
  1560. *
  1561. * if instream[k] = n
  1562. * peak k has been assigned to stream n
  1563. *
  1564. * If there are MORE peaks Than there are peak-streams.
  1565. *
  1566. * if instream[k] = n
  1567. * peak n has been assigned to stream k
  1568. *
  1569. * Attempt to place found peaks within the pitch-streams whose (putative frqs) are defined by interpolation between
  1570. * last window with max number of peaks and
  1571. * next window with max number of peaks
  1572. */
  1573. int stream_peaks(float *peakfrq,float *peakamp,float *maxpeakfrq,float *lastmaxpeakfrq,float *streamfrq,
  1574. int wcnt,int lastmax,int firstmax,int maxpeakcnt,int peakcnt,int *instream,
  1575. float *streampeakfrq,float *streampeakamp,dataptr dz)
  1576. {
  1577. int *combo;
  1578. int k, n, combo_cnt, morepeaksthanstreams; // combo_cnt is number of items (peaks) for which we must find
  1579. double minratiosum = HUGE, thisfrq; // all possible combinations..... e.g.
  1580. int step, loc; // Either: Number of ways to assign 5 peaks to 8 streams
  1581. double ratio; // Or: Number of ways to select 5 peaks from 8 peaks, to assign to 5 streams
  1582. if(dz->mode ==1) {
  1583. step = firstmax - lastmax; // Window-count gap between previous and next windows having full (max) set of peaks.
  1584. loc = wcnt - lastmax; // Window-count distance from previous full-peak-set to current window.
  1585. ratio = (double)loc/(double)step; // Find proportion of the gap this represents.
  1586. for(k=0;k < maxpeakcnt;k++) {
  1587. thisfrq = maxpeakfrq[k] - lastmaxpeakfrq[k];
  1588. thisfrq *= ratio; // Establish where each stream frq "should" lie, by interpolation
  1589. thisfrq += lastmaxpeakfrq[k]; // between preceding and following windows containing MAX number of peaks
  1590. streamfrq[k] = (float)thisfrq;
  1591. }
  1592. } // NB for MODE2 streamfrqs are already set
  1593. if (peakcnt < maxpeakcnt) {
  1594. combo_cnt = peakcnt; // e.g. 5(peakcnt) peaks are to be assigned to 8(maxpeakcnt) streams
  1595. morepeaksthanstreams = 0;
  1596. } else { // e.g. 5(maxpeakcnt) of 8 peaks are to be assigned to 5(peakcnt) streams
  1597. combo_cnt = maxpeakcnt;
  1598. morepeaksthanstreams = 1; // In either case we need to find all ways to distrib 5 objects among 8 locations
  1599. }
  1600. if((combo = (int *)malloc(combo_cnt * sizeof(int)))==NULL) {
  1601. sprintf(errstr,"No memory for combinations array\n");
  1602. return(MEMORY_ERROR);
  1603. }
  1604. // Assign peaks to streams in all possible combinations
  1605. combinations(combo,0,0,maxpeakcnt - peakcnt,peakcnt,maxpeakcnt,&minratiosum,instream,peakfrq,maxpeakfrq,streamfrq,morepeaksthanstreams);
  1606. // And calculate best fit -
  1607. // i.e. least deviation of frqs-of-peaks from frqs-of-streams to which they are assigned
  1608. if(peakcnt < maxpeakcnt) {
  1609. k = 0; // from the predicted frq of the peak-stream
  1610. for(n=0;n<maxpeakcnt;n++) {
  1611. if(k >= peakcnt) { // Once all active-peaks have been assigned to streams,
  1612. streampeakfrq[n] = streamfrq[n]; // force remaining streams to zero amp
  1613. streampeakamp[n] = 0.0f;
  1614. } else if(instream[k] == n) { // If this active-peak(k) has been assigned to current stream(n)
  1615. streampeakfrq[n] = peakfrq[k]; // assign active-peak frq and amp to that stream
  1616. streampeakamp[n] = peakamp[k];
  1617. k++; // and get next active peak;
  1618. } else {
  1619. streampeakfrq[n] = streamfrq[n];// Otherwise, force stream to zero amp
  1620. streampeakamp[n] = 0.0f;
  1621. }
  1622. }
  1623. for(n=0;n<maxpeakcnt;n++) {
  1624. peakfrq[n] = streampeakfrq[n]; // Rewrite the complete frq and amp arrays for all peak streams
  1625. peakamp[n] = streampeakamp[n];
  1626. }
  1627. } else {
  1628. k = 0; // from the existing peak frqs
  1629. for(n=0;n<peakcnt;n++) {
  1630. if(instream[k] == n) { // If this peak(n) has been assigned to stream k
  1631. streampeakfrq[k] = peakfrq[n]; // assign peak frq and amp to that stream
  1632. streampeakamp[k] = peakamp[n];
  1633. if(++k >= maxpeakcnt) // and get next stream
  1634. break;
  1635. }
  1636. }
  1637. for(n=0;n<maxpeakcnt;n++) {
  1638. peakfrq[n] = streampeakfrq[n]; // Rewrite the complete frq and amp arrays for all peak streams
  1639. peakamp[n] = streampeakamp[n];
  1640. }
  1641. }
  1642. return FINISHED;
  1643. }
  1644. /************************************ COMBINATIONS **************************************
  1645. *
  1646. * Find all possible ways of assigning peakcnt PEAKS to STREAMS
  1647. *
  1648. */
  1649. void combinations(int *combo,int k,int i, int j,int peakcnt,int maxpeakcnt,double *minratiosum,int *instream,
  1650. float *peakfrq,float *maxpeakfrq,float *streamfrq,int morepeaksthanstreams)
  1651. {
  1652. int n;
  1653. if(k >= peakcnt) {
  1654. if(morepeaksthanstreams) // If more peaks than streams
  1655. find_best_fit(combo,maxpeakcnt,minratiosum,instream,maxpeakfrq,peakfrq);
  1656. else // If less peaks than streams
  1657. find_best_fit(combo,peakcnt,minratiosum,instream,peakfrq,streamfrq);
  1658. return;
  1659. }
  1660. for(n = i;n <= j;n++) {
  1661. combo[k] = n;
  1662. combinations(combo,k+1,n+1,j+1,peakcnt,maxpeakcnt,minratiosum,instream,peakfrq,maxpeakfrq,streamfrq,morepeaksthanstreams);
  1663. }
  1664. }
  1665. /************************************ FIND_BEST_FIT_LESS **************************************
  1666. *
  1667. * Here we try a smaller number of peaks in a larger number of streams
  1668. *
  1669. * Find deviation of actual peak frqs from predicted frqs of streams assigned.
  1670. * If it is lower than previous deviation, remember the assigned-streams.
  1671. */
  1672. void find_best_fit(int *combo,int smallsetcnt,double *minratiosum,int *instream,float *smallset,float *largeset)
  1673. {
  1674. int n = 0;
  1675. double ratiosum = 0.0, ratio;
  1676. while(n < smallsetcnt) {
  1677. if(smallset[n] > largeset[combo[n]]) // Compare peak frq with predited frequency of stream
  1678. ratio = smallset[n]/largeset[combo[n]]; // to which it is assigned in THIS combination
  1679. else
  1680. ratio = largeset[combo[n]]/smallset[n];
  1681. ratiosum += ratio; // Sum frq ratios for all peaks
  1682. n++;
  1683. }
  1684. if(ratiosum < *minratiosum) { // Compare with existing minimum ratio sum
  1685. *minratiosum = ratiosum; // and if less (better fit)
  1686. for(n=0;n<smallsetcnt;n++) // Remember how peaks are assigned to streams
  1687. instream[n] = combo[n];
  1688. }
  1689. }
  1690. /************************************ GET_INITIAL_DATA **************************************
  1691. *
  1692. * Find loudesnt window in entire file: used to set AMPFLOOR.
  1693. * If output data is to be assigned to peak streams ..
  1694. * find maximum number of peaks in any of the windows, remembering the frq values in the first such window.
  1695. */
  1696. int get_initial_data(float *maxwinamp,int *peakcnt,int *maxpeakcnt,int *firstmax,float *medianarray,int *chanarray,char *peakchan,
  1697. float *peakfrq,float *peakamp,int *peaknos,float *maxpeakfrq,float *lastmaxpeakfrq,double frqratio,
  1698. int bincnt,float *binlofrq,int *pitchbin,float *bintrof,float *streamfrq,dataptr dz)
  1699. {
  1700. int wcnt = 0, samps_read, vc, k, j;
  1701. double time = 0.0;
  1702. int lastval;
  1703. int gotmin = 0;
  1704. int done;
  1705. if(dz->mode > 0)
  1706. fprintf(stdout,"INFO: Searching for maximum number of peaks, and maximum window amplitude.\n");
  1707. else
  1708. fprintf(stdout,"INFO: Searching for maximum window amplitude.\n");
  1709. fflush(stdout);
  1710. while((samps_read = fgetfbufEx(dz->bigfbuf,dz->buflen,dz->ifd[0],0)) > 0) {
  1711. for( vc = 0; vc < dz->wanted; vc += 2) {
  1712. if(dz->flbufptr[0][AMPP] > *maxwinamp)
  1713. *maxwinamp = dz->flbufptr[0][AMPP];
  1714. }
  1715. *peakcnt = locate_peaks(medianarray,chanarray,peakchan,peakfrq,peakamp,frqratio,dz);
  1716. switch(dz->mode) {
  1717. case(1): // SET UP NORMAL STREAMING
  1718. peaknos[wcnt] = *peakcnt; // Store number of peaks in each window
  1719. if(*peakcnt > *maxpeakcnt) {
  1720. *maxpeakcnt = *peakcnt;
  1721. *firstmax = wcnt;
  1722. for(k=0;k<*peakcnt;k++) { // Stores frqs of peaks in (1st) window with max no. of peaks
  1723. maxpeakfrq[k] = peakfrq[k];
  1724. lastmaxpeakfrq[k] = peakfrq[k];
  1725. }
  1726. }
  1727. break;
  1728. case(2): // DO STATISTICS ON PEAKS
  1729. case(3):
  1730. for(k=0;k<*peakcnt;k++) {
  1731. done = 0;
  1732. for(j = 1; j < bincnt; j++) {
  1733. if(peakfrq[k] < binlofrq[j]) {
  1734. (pitchbin[j-1])++;
  1735. done = 1;
  1736. break;
  1737. }
  1738. }
  1739. if(!done)
  1740. (pitchbin[j-1])++;
  1741. }
  1742. }
  1743. wcnt++;
  1744. dz->total_samps_read += samps_read;
  1745. time += dz->frametime;
  1746. displaytime(time,dz);
  1747. }
  1748. if(samps_read < 0) {
  1749. sprintf(errstr,"Failed to read samples after sample %d\n",dz->total_samps_read);
  1750. return(SYSTEM_ERROR);
  1751. }
  1752. if(sndseekEx(dz->ifd[0],0,0)< 0) {
  1753. sprintf(errstr,"Failed to seek to start of file, after initial read\n");
  1754. return(SYSTEM_ERROR);
  1755. }
  1756. if(dz->mode == 2 || dz->mode == 3) { // Find peaks among semitonal pitch-bins
  1757. j = 0;
  1758. lastval = -1;
  1759. gotmin = 0;
  1760. for(k=0;k<bincnt;k++) {
  1761. if(gotmin) {
  1762. if(pitchbin[k] < lastval) { // PASSED OVER A PEAK
  1763. streamfrq[j] = (binlofrq[k-1] + binlofrq[k])/2;
  1764. j++;
  1765. gotmin = 0;
  1766. }
  1767. } else if(pitchbin[k] > lastval)
  1768. gotmin = 1;
  1769. lastval = pitchbin[k];
  1770. }
  1771. *maxpeakcnt = j;
  1772. }
  1773. dz->total_samps_read = 0;
  1774. return FINISHED;
  1775. }
  1776. /************************************ GET_NEXT_WINDOW_WITH_MAX_NUMBER_OF_PEAKS **************************************
  1777. *
  1778. * Seek to next window which has the max number of peaks, and remember these peaks.
  1779. * These peaks, and peaks in previous window with max number of peaks,
  1780. * are used to calculate the effective frq of the pitch-streams in any intervening windows
  1781. * which do not have the same number of peaks (MODE2 = internal mode 1).
  1782. */
  1783. int get_next_window_with_max_number_of_peaks(int *peakcnt,int maxpeakcnt,float *lastmaxpeakfrq,float *maxpeakfrq,
  1784. int *firstmax,int *lastmax,int wcnt,double frqratio,
  1785. int *peaknos,float *medianarray,int *chanarray,char *peakchan,float *peakfrq,float *peakamp,dataptr dz)
  1786. {
  1787. int k,j,samps_read;
  1788. for(k=0;k<*peakcnt;k++)
  1789. lastmaxpeakfrq[k] = maxpeakfrq[k];
  1790. *lastmax = *firstmax;
  1791. j = wcnt + 1;
  1792. while(j < dz->wlength) {
  1793. if(peaknos[j] == maxpeakcnt) { // Find next window that has all the maximum number of peaks
  1794. if((sndseekEx(dz->ifd[0],j * dz->buflen,0)) < 0) {
  1795. sprintf(errstr,"File seek to find next maxpeak window, failed.\n");
  1796. return(SYSTEM_ERROR);
  1797. } // Get the peaks in that window
  1798. if((samps_read = fgetfbufEx(dz->bigfbuf,dz->buflen,dz->ifd[0],0)) < 0) {
  1799. sprintf(errstr,"Sample Read Failed After Seeking for next maximum peakcnt window\n");
  1800. return(SYSTEM_ERROR);
  1801. } // Get the peaks in that window
  1802. *peakcnt = locate_peaks(medianarray,chanarray,peakchan,peakfrq,peakamp,frqratio,dz);
  1803. for(k=0;k<*peakcnt;k++) // Update the maxpeak array
  1804. maxpeakfrq[k] = peakfrq[k];
  1805. if(sndseekEx(dz->ifd[0],wcnt * dz->buflen,0)<0) {
  1806. sprintf(errstr,"File seek AFTER finding next maxpeak window, failed.\n");
  1807. return(SYSTEM_ERROR);
  1808. }
  1809. break; // Seek back to original window position
  1810. }
  1811. j++;
  1812. } // If no further window is found with max no. of peaks, maxpeakfrq does not change
  1813. *firstmax = j; // and processing continues to end of file
  1814. return FINISHED;
  1815. }
  1816. /************************************ DISPLAYTIME **************************************/
  1817. void displaytime(double secs,dataptr dz)
  1818. {
  1819. double float_time;
  1820. int display_time,mins;
  1821. if(sloom) {
  1822. float_time = min(1.0,(double)dz->total_samps_read/(double)dz->insams[0]);
  1823. display_time = round(float_time * PBAR_LENGTH);
  1824. fprintf(stdout,"TIME: %d\n",display_time);
  1825. fflush(stdout);
  1826. } else {
  1827. mins = (int)(secs/60.0); /* TRUNCATE */
  1828. secs -= (double)(mins * 60);
  1829. fprintf(stdout,"\r%d min %5.2lf sec", mins, secs);
  1830. }
  1831. }