spectstr.c 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661
  1. // This algorithm finds the pitch (if any) in each window,
  2. // marking no-pitch-found with a -1 value.
  3. // It discards any windows falling below a threshold amplitude.
  4. // (It can ,optionally, smooth the output data, and remove "blips"
  5. // i.e. "pitches lasting for no more than 1 window".
  6. // but this is not essential, as the statistical survey to follow
  7. // should normally eliminate these anomalies.
  8. //
  9. // It then allots the found pitches to 1/8th semitone bins,
  10. // and finds the bin with the most entries.
  11. // This can be done by counting the windows that fall into the bin,
  12. // or by summing the total-loudnesses of the windows that fall into the bin.
  13. // The bin with the highest score/weight is taken to be the most prominent pitch.
  14. //
  15. // Note that, if the pitch is wrong but falls on a prominent harmonic,
  16. // and the tuning is to a harmonic field with a large number of pitches to tune to,
  17. // such an error may still lead to an appropriate transposition,
  18. // as the real root with be transposed along with the prominent harmonic.
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <structures.h>
  22. #include <tkglobals.h>
  23. #include <pnames.h>
  24. #include <filetype.h>
  25. #include <processno.h>
  26. #include <modeno.h>
  27. #include <arrays.h>
  28. #include <flags.h>
  29. #include <logic.h>
  30. #include <fmnts.h>
  31. #include <formants.h>
  32. #include <globcon.h>
  33. #include <cdpmain.h>
  34. #include <math.h>
  35. #include <mixxcon.h>
  36. #include <osbind.h>
  37. #include <standalone.h>
  38. #include <speccon.h>
  39. #include <ctype.h>
  40. #include <sfsys.h>
  41. #include <string.h>
  42. #include <srates.h>
  43. #ifdef unix
  44. #define round lround
  45. #endif
  46. static double st_intun, st_noise;
  47. static int st_wndws;
  48. #define do_decohere is_rectified
  49. #define POSMIN 200
  50. #define DISC_RATIO 1 // Proportion of channels to discohere
  51. #define DISC_RAND 2 // Randomisation of frequency in discohered channels
  52. char errstr[2400];
  53. int anal_infiles = 1;
  54. int sloom = 0;
  55. int sloombatch = 0;
  56. const char* cdp_version = "7.1.0";
  57. /* CDP LIBRARY FUNCTIONS TRANSFERRED HERE */
  58. static int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist);
  59. static int set_vflgs(aplptr ap,char *optflags,int optcnt,char *optlist,
  60. char *varflags,int vflagcnt, int vparamcnt,char *varlist);
  61. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  62. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  63. static int mark_parameter_types(dataptr dz,aplptr ap);
  64. static int establish_application(dataptr dz);
  65. static int application_init(dataptr dz);
  66. static int initialise_vflags(dataptr dz);
  67. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  68. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  69. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  70. static int assign_file_data_storage(int infilecnt,dataptr dz);
  71. /* CDP LIB FUNCTION MODIFIED TO AVOID CALLING setup_particular_application() */
  72. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  73. /* SIMPLIFICATION OF LIB FUNC TO APPLY TO JUST THIS FUNCTION */
  74. static int parse_infile_and_check_type(char **cmdline,dataptr dz);
  75. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,int is_launched,dataptr dz);
  76. static int setup_the_application(dataptr dz);
  77. static int setup_the_param_ranges_and_defaults(dataptr dz);
  78. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  79. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  80. static int get_the_mode_no(char *str, dataptr dz);
  81. /* BYPASS LIBRARY GLOBAL FUNCTION TO GO DIRECTLY TO SPECIFIC APPLIC FUNCTIONS */
  82. extern int allocate_tstretch_buffer(dataptr dz);
  83. extern int check_for_enough_tstretch_brkpnt_vals(dataptr dz);
  84. extern int setup_internal_params_for_tstretch(dataptr dz);
  85. extern int retrograde_sequence_of_time_intervals(int endtime,int count,double *startptr,dataptr dz);
  86. extern double calculate_position(int x,double param0,double param1,double param2);
  87. extern int calc_position_output_wdws_relative_to_input_wdws_for_increasing_stretch
  88. (int *thatwindow,int startwindow,int count,double param0,double param1,double param2,dataptr dz);
  89. extern int calc_position_output_wdws_relative_to_input_wdws_for_decreasing_stretch
  90. (int *thatwindow,int startwindow,int count,int totaldur,double param0,double param1,double param2,dataptr dz);
  91. extern double calculate_number_of_output_windows(double startwdur,double endwdur,int totaldur);
  92. extern int advance_along_input_windows(int wdw_to_advance,int atend,dataptr dz);
  93. extern int timestretch_this_segment(int *thatwindow,int startwindow,double thiswdur,double nextwdur,int totaldur,dataptr dz);
  94. extern int get_both_vals_from_brktable(double *thistime,double *thisstretch,int brktab_no,dataptr dz);
  95. extern int divide_time_into_equal_increments(int *thatwindow,int startwindow,double dur,int count,dataptr dz);
  96. extern int do_timestretching(int *thatwindow,int count,dataptr dz);
  97. extern int do_timevariable_timestretch(int *thatwindow,dataptr dz);
  98. extern int do_constant_timestretch(int *thatwindow,dataptr dz);
  99. extern int spectstretch(dataptr dz);
  100. extern int decohere(float *fbuf,dataptr dz);
  101. /**************************************** MAIN *********************************************/
  102. int main(int argc,char *argv[])
  103. {
  104. int exit_status;
  105. dataptr dz = NULL;
  106. char **cmdline;
  107. int cmdlinecnt;
  108. aplptr ap;
  109. int is_launched = FALSE;
  110. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  111. fprintf(stdout,"%s\n",cdp_version);
  112. fflush(stdout);
  113. return 0;
  114. }
  115. /* CHECK FOR SOUNDLOOM */
  116. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  117. sloom = 0;
  118. sloombatch = 1;
  119. }
  120. if(sflinit("cdp")){
  121. sfperror("cdp: initialisation\n");
  122. return(FAILED);
  123. }
  124. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  125. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  126. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  127. return(FAILED);
  128. }
  129. if(!sloom) {
  130. if(argc == 1) {
  131. usage1();
  132. return(FAILED);
  133. } else if(argc == 2) {
  134. usage2(argv[1]);
  135. return(FAILED);
  136. }
  137. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  138. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  139. return(FAILED);
  140. }
  141. cmdline = argv;
  142. cmdlinecnt = argc;
  143. if((get_the_process_no(argv[0],dz))<0)
  144. return(FAILED);
  145. cmdline++;
  146. cmdlinecnt--;
  147. dz->maxmode = 0;
  148. if((exit_status = setup_the_application(dz))<0) {
  149. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  150. return(FAILED);
  151. }
  152. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  153. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  154. return(FAILED);
  155. }
  156. } else {
  157. //parse_TK_data() =
  158. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  159. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  160. return(exit_status);
  161. }
  162. }
  163. ap = dz->application;
  164. // parse_infile_and_hone_type() =
  165. if((exit_status = parse_infile_and_check_type(cmdline,dz))<0) {
  166. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  167. return(FAILED);
  168. }
  169. // setup_param_ranges_and_defaults() =
  170. if((exit_status = setup_the_param_ranges_and_defaults(dz))<0) {
  171. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  172. return(FAILED);
  173. }
  174. if((exit_status = set_internalparam_data("di",ap))<0) { //RWD removed extra 'exit_status'
  175. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  176. return(FAILED);
  177. }
  178. // open_first_infile CDP LIB
  179. if((exit_status = open_first_infile(cmdline[0],dz))<0) {
  180. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  181. return(FAILED);
  182. }
  183. cmdlinecnt--;
  184. cmdline++;
  185. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,is_launched,dz))<0) {
  186. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  187. return(FAILED);
  188. }
  189. // handle_formants() redundant
  190. // handle_special_data() redundant except
  191. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  192. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  193. return(FAILED);
  194. }
  195. //check_param_validity_and_consistency() ....
  196. if((exit_status = check_for_enough_tstretch_brkpnt_vals(dz))<0) {
  197. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  198. return(MEMORY_ERROR);
  199. }
  200. if((exit_status = setup_internal_params_for_tstretch(dz))<0) {
  201. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  202. return(FAILED);
  203. }
  204. is_launched = TRUE;
  205. if((exit_status = allocate_tstretch_buffer(dz))<0) {
  206. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  207. return(MEMORY_ERROR);
  208. }
  209. if((dz->iparray[0] = (int *)malloc(dz->clength * sizeof(int)))==NULL) {
  210. sprintf(errstr,"INSUFFICIENT MEMORY for channel sorting array.\n");
  211. return(MEMORY_ERROR);
  212. }
  213. display_virtual_time(0L,dz);
  214. //spec_process_file =
  215. if((exit_status = spectstretch(dz)) < 0) {
  216. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  217. return(FAILED);
  218. }
  219. if((exit_status = complete_output(dz))<0) { // CDP LIB
  220. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  221. return(FAILED);
  222. }
  223. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  224. free(dz);
  225. return(SUCCEEDED);
  226. }
  227. /**********************************************
  228. REPLACED CDP LIB FUNCTIONS
  229. **********************************************/
  230. /****************************** SET_PARAM_DATA *********************************/
  231. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  232. {
  233. ap->special_data = (char)special_data;
  234. ap->param_cnt = (char)paramcnt;
  235. ap->max_param_cnt = (char)maxparamcnt;
  236. if(ap->max_param_cnt>0) {
  237. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  238. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  239. return(MEMORY_ERROR);
  240. }
  241. strcpy(ap->param_list,paramlist);
  242. }
  243. return(FINISHED);
  244. }
  245. /****************************** SET_VFLGS *********************************/
  246. int set_vflgs
  247. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  248. {
  249. ap->option_cnt = (char) optcnt; /*RWD added cast */
  250. if(optcnt) {
  251. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  252. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  253. return(MEMORY_ERROR);
  254. }
  255. strcpy(ap->option_list,optlist);
  256. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  257. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  258. return(MEMORY_ERROR);
  259. }
  260. strcpy(ap->option_flags,optflags);
  261. }
  262. ap->vflag_cnt = (char) vflagcnt;
  263. ap->variant_param_cnt = (char) vparamcnt;
  264. if(vflagcnt) {
  265. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  266. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  267. return(MEMORY_ERROR);
  268. }
  269. strcpy(ap->variant_list,varlist);
  270. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  271. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  272. return(MEMORY_ERROR);
  273. }
  274. strcpy(ap->variant_flags,varflags);
  275. }
  276. return(FINISHED);
  277. }
  278. /***************************** APPLICATION_INIT **************************/
  279. int application_init(dataptr dz)
  280. {
  281. int exit_status, n;
  282. int storage_cnt;
  283. int tipc, brkcnt;
  284. aplptr ap = dz->application;
  285. if(ap->vflag_cnt>0)
  286. initialise_vflags(dz);
  287. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  288. ap->total_input_param_cnt = (char)tipc;
  289. if(tipc>0) {
  290. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  291. return(exit_status);
  292. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  293. return(exit_status);
  294. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  295. return(exit_status);
  296. }
  297. brkcnt = tipc;
  298. if(brkcnt>0) {
  299. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  300. return(exit_status);
  301. }
  302. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  303. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  304. return(exit_status);
  305. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  306. return(exit_status);
  307. }
  308. if((exit_status = mark_parameter_types(dz,ap))<0)
  309. return(exit_status);
  310. // establish_infile_constants() replaced by
  311. dz->infilecnt = 1;
  312. dz->iarray_cnt = 1;
  313. dz->array_cnt = 2;
  314. dz->ptr_cnt = 4;
  315. if((dz->parray = (double **)malloc(dz->array_cnt * sizeof(double *)))==NULL) {
  316. sprintf(errstr,"INSUFFICIENT MEMORY for internal double arrays.\n");
  317. return(MEMORY_ERROR);
  318. }
  319. for(n=0;n<dz->array_cnt;n++)
  320. dz->parray[n] = NULL;
  321. if((dz->iparray = (int **)malloc(dz->iarray_cnt * sizeof(int *)))==NULL) {
  322. sprintf(errstr,"INSUFFICIENT MEMORY for internal integer arrays.\n");
  323. return(MEMORY_ERROR);
  324. }
  325. for(n=0;n<dz->iarray_cnt;n++)
  326. dz->iparray[n] = NULL;
  327. if((dz->ptr = (double **)malloc(dz->ptr_cnt * sizeof(double *)))==NULL) {
  328. sprintf(errstr,"INSUFFICIENT MEMORY for internal pointer arrays.\n");
  329. return(MEMORY_ERROR);
  330. }
  331. for(n=0;n<dz->ptr_cnt;n++)
  332. dz->ptr[n] = NULL;
  333. return(FINISHED);
  334. }
  335. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  336. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  337. {
  338. int n;
  339. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  340. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  341. return(MEMORY_ERROR);
  342. }
  343. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  344. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  345. return(MEMORY_ERROR);
  346. }
  347. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  348. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  349. return(MEMORY_ERROR);
  350. }
  351. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  352. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  353. return(MEMORY_ERROR);
  354. }
  355. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  356. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  357. return(MEMORY_ERROR);
  358. }
  359. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  360. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  361. return(MEMORY_ERROR);
  362. }
  363. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  364. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  365. return(MEMORY_ERROR);
  366. }
  367. for(n=0;n<brkcnt;n++) {
  368. dz->brk[n] = NULL;
  369. dz->brkptr[n] = NULL;
  370. dz->brkinit[n] = 0;
  371. dz->brksize[n] = 0;
  372. }
  373. return(FINISHED);
  374. }
  375. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  376. /* RWD mallo changed to calloc; helps debug verison run as release! */
  377. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  378. {
  379. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  380. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  381. return(MEMORY_ERROR);
  382. }
  383. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  384. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  385. return(MEMORY_ERROR);
  386. }
  387. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  388. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  389. return(MEMORY_ERROR);
  390. }
  391. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  392. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  393. return(MEMORY_ERROR);
  394. }
  395. return(FINISHED);
  396. }
  397. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  398. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  399. {
  400. int n;
  401. for(n=0;n<storage_cnt;n++) {
  402. dz->is_int[n] = (char)0;
  403. dz->no_brk[n] = (char)0;
  404. }
  405. return(FINISHED);
  406. }
  407. /***************************** MARK_PARAMETER_TYPES **************************/
  408. int mark_parameter_types(dataptr dz,aplptr ap)
  409. {
  410. int n, m; /* PARAMS */
  411. for(n=0;n<ap->max_param_cnt;n++) {
  412. switch(ap->param_list[n]) {
  413. case('0'): break; /* dz->is_active[n] = 0 is default */
  414. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  415. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  416. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  417. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  418. default:
  419. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  420. return(PROGRAM_ERROR);
  421. }
  422. } /* OPTIONS */
  423. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  424. switch(ap->option_list[n]) {
  425. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  426. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  427. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  428. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  429. default:
  430. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  431. return(PROGRAM_ERROR);
  432. }
  433. } /* VARIANTS */
  434. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  435. switch(ap->variant_list[n]) {
  436. case('0'): break;
  437. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  438. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  439. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  440. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  441. default:
  442. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  443. return(PROGRAM_ERROR);
  444. }
  445. } /* INTERNAL */
  446. for(n=0,
  447. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  448. switch(ap->internal_param_list[n]) {
  449. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  450. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  451. case('d'): dz->no_brk[m] = (char)1; break;
  452. default:
  453. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  454. return(PROGRAM_ERROR);
  455. }
  456. }
  457. return(FINISHED);
  458. }
  459. /***************************** HANDLE_THE_OUTFILE **************************/
  460. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,int is_launched,dataptr dz)
  461. {
  462. int exit_status;
  463. char *filename = NULL;
  464. filename = (*cmdline)[0];
  465. strcpy(dz->outfilename,filename);
  466. if((exit_status = create_sized_outfile(filename,dz))<0)
  467. return(exit_status);
  468. (*cmdline)++;
  469. (*cmdlinecnt)--;
  470. return(FINISHED);
  471. }
  472. /***************************** ESTABLISH_APPLICATION **************************/
  473. int establish_application(dataptr dz)
  474. {
  475. aplptr ap;
  476. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  477. sprintf(errstr,"establish_application()\n");
  478. return(MEMORY_ERROR);
  479. }
  480. ap = dz->application;
  481. memset((char *)ap,0,sizeof(struct applic));
  482. return(FINISHED);
  483. }
  484. /************************* INITIALISE_VFLAGS *************************/
  485. int initialise_vflags(dataptr dz)
  486. {
  487. int n;
  488. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  489. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  490. return(MEMORY_ERROR);
  491. }
  492. for(n=0;n<dz->application->vflag_cnt;n++)
  493. dz->vflag[n] = FALSE;
  494. return FINISHED;
  495. }
  496. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  497. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  498. {
  499. int n;
  500. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  501. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  502. return(MEMORY_ERROR);
  503. }
  504. for(n=0;n<tipc;n++)
  505. ap->default_val[n] = 0.0;
  506. return(FINISHED);
  507. }
  508. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  509. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  510. {
  511. int n;
  512. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  513. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  514. return(MEMORY_ERROR);
  515. }
  516. for(n=0;n<tipc;n++)
  517. dz->is_active[n] = (char)0;
  518. return(FINISHED);
  519. }
  520. /************************* SETUP_THE_APPLICATION *******************/
  521. int setup_the_application(dataptr dz)
  522. {
  523. int exit_status;
  524. aplptr ap;
  525. if((exit_status = establish_application(dz))<0) // GLOBAL
  526. return(FAILED);
  527. ap = dz->application;
  528. // SEE parstruct FOR EXPLANATION of next 2 functions
  529. if((exit_status = set_param_data(ap,0,3,3,"Ddd"))< 0)
  530. return(FAILED);
  531. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))< 0)
  532. return(FAILED);
  533. // set_legal_infile_structure -->
  534. dz->has_otherfile = FALSE;
  535. // assign_process_logic -->
  536. dz->input_data_type = ANALFILE_ONLY;
  537. dz->process_type = BIG_ANALFILE;
  538. dz->outfiletype = ANALFILE_OUT;
  539. return application_init(dz); //GLOBAL
  540. }
  541. /************************* PARSE_INFILE_AND_CHECK_TYPE *******************/
  542. int parse_infile_and_check_type(char **cmdline,dataptr dz)
  543. {
  544. int exit_status;
  545. infileptr infile_info;
  546. if(!sloom) {
  547. if((infile_info = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  548. sprintf(errstr,"INSUFFICIENT MEMORY for infile structure to test file data.");
  549. return(MEMORY_ERROR);
  550. } else if((exit_status = cdparse(cmdline[0],infile_info))<0) {
  551. sprintf(errstr,"Failed tp parse input file %s\n",cmdline[0]);
  552. return(PROGRAM_ERROR);
  553. } else if(infile_info->filetype != ANALFILE) {
  554. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  555. return(DATA_ERROR);
  556. } else if((exit_status = copy_parse_info_to_main_structure(infile_info,dz))<0) {
  557. sprintf(errstr,"Failed to copy file parsing information\n");
  558. return(PROGRAM_ERROR);
  559. }
  560. free(infile_info);
  561. }
  562. dz->clength = dz->wanted / 2;
  563. dz->chwidth = dz->nyquist/(double)(dz->clength-1);
  564. dz->halfchwidth = dz->chwidth/2.0;
  565. return(FINISHED);
  566. }
  567. /************************* SETUP_THE_PARAM_RANGES_AND_DEFAULTS *******************/
  568. int setup_the_param_ranges_and_defaults(dataptr dz)
  569. {
  570. int exit_status;
  571. aplptr ap = dz->application;
  572. // set_param_ranges()
  573. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  574. // NB total_input_param_cnt is > 0 !!!s
  575. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  576. return(FAILED);
  577. // get_param_ranges()
  578. ap->lo[TSTR_STRETCH] = 0.0001;
  579. ap->hi[TSTR_STRETCH] = 10000;
  580. ap->default_val[TSTR_STRETCH] = 1.0;
  581. ap->lo[DISC_RATIO] = 0.0;
  582. ap->hi[DISC_RATIO] = 1.0;
  583. ap->default_val[DISC_RATIO] = 0.75;
  584. ap->lo[DISC_RAND] = 0.0;
  585. ap->hi[DISC_RAND] = 1.0;
  586. ap->default_val[DISC_RAND] = 0.5;
  587. dz->maxmode = 0;
  588. if(!sloom)
  589. put_default_vals_in_all_params(dz);
  590. return(FINISHED);
  591. }
  592. /********************************* PARSE_SLOOM_DATA *********************************/
  593. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  594. {
  595. int exit_status;
  596. int cnt = 1, infilecnt;
  597. int filesize, insams, inbrksize;
  598. double dummy;
  599. int true_cnt = 0;
  600. aplptr ap;
  601. while(cnt<=PRE_CMDLINE_DATACNT) {
  602. if(cnt > argc) {
  603. sprintf(errstr,"Insufficient data sent from TK\n");
  604. return(DATA_ERROR);
  605. }
  606. switch(cnt) {
  607. case(1):
  608. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  609. sprintf(errstr,"Cannot read process no. sent from TK\n");
  610. return(DATA_ERROR);
  611. }
  612. break;
  613. case(2):
  614. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  615. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  616. return(DATA_ERROR);
  617. }
  618. if(dz->mode > 0)
  619. dz->mode--;
  620. //setup_particular_application() =
  621. if((exit_status = setup_the_application(dz))<0)
  622. return(exit_status);
  623. ap = dz->application;
  624. break;
  625. case(3):
  626. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  627. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  628. return(DATA_ERROR);
  629. }
  630. if(infilecnt < 1) {
  631. true_cnt = cnt + 1;
  632. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  633. }
  634. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  635. return(exit_status);
  636. break;
  637. case(INPUT_FILETYPE+4):
  638. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  639. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  640. return(DATA_ERROR);
  641. }
  642. break;
  643. case(INPUT_FILESIZE+4):
  644. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  645. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  646. return(DATA_ERROR);
  647. }
  648. dz->insams[0] = filesize;
  649. break;
  650. case(INPUT_INSAMS+4):
  651. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  652. sprintf(errstr,"Cannot read insams sent from TK\n");
  653. return(DATA_ERROR);
  654. }
  655. dz->insams[0] = insams;
  656. break;
  657. case(INPUT_SRATE+4):
  658. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  659. sprintf(errstr,"Cannot read srate sent from TK\n");
  660. return(DATA_ERROR);
  661. }
  662. break;
  663. case(INPUT_CHANNELS+4):
  664. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  665. sprintf(errstr,"Cannot read channels sent from TK\n");
  666. return(DATA_ERROR);
  667. }
  668. break;
  669. case(INPUT_STYPE+4):
  670. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  671. sprintf(errstr,"Cannot read stype sent from TK\n");
  672. return(DATA_ERROR);
  673. }
  674. break;
  675. case(INPUT_ORIGSTYPE+4):
  676. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  677. sprintf(errstr,"Cannot read origstype sent from TK\n");
  678. return(DATA_ERROR);
  679. }
  680. break;
  681. case(INPUT_ORIGRATE+4):
  682. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  683. sprintf(errstr,"Cannot read origrate sent from TK\n");
  684. return(DATA_ERROR);
  685. }
  686. break;
  687. case(INPUT_MLEN+4):
  688. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  689. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  690. return(DATA_ERROR);
  691. }
  692. break;
  693. case(INPUT_DFAC+4):
  694. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  695. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  696. return(DATA_ERROR);
  697. }
  698. break;
  699. case(INPUT_ORIGCHANS+4):
  700. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  701. sprintf(errstr,"Cannot read origchans sent from TK\n");
  702. return(DATA_ERROR);
  703. }
  704. break;
  705. case(INPUT_SPECENVCNT+4):
  706. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  707. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  708. return(DATA_ERROR);
  709. }
  710. dz->specenvcnt = dz->infile->specenvcnt;
  711. break;
  712. case(INPUT_WANTED+4):
  713. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  714. sprintf(errstr,"Cannot read wanted sent from TK\n");
  715. return(DATA_ERROR);
  716. }
  717. break;
  718. case(INPUT_WLENGTH+4):
  719. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  720. sprintf(errstr,"Cannot read wlength sent from TK\n");
  721. return(DATA_ERROR);
  722. }
  723. break;
  724. case(INPUT_OUT_CHANS+4):
  725. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  726. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  727. return(DATA_ERROR);
  728. }
  729. break;
  730. /* RWD these chanegs to samps - tk will have to deal with that! */
  731. case(INPUT_DESCRIPTOR_BYTES+4):
  732. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  733. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  734. return(DATA_ERROR);
  735. }
  736. break;
  737. case(INPUT_IS_TRANSPOS+4):
  738. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  739. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  740. return(DATA_ERROR);
  741. }
  742. break;
  743. case(INPUT_COULD_BE_TRANSPOS+4):
  744. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  745. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  746. return(DATA_ERROR);
  747. }
  748. break;
  749. case(INPUT_COULD_BE_PITCH+4):
  750. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  751. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  752. return(DATA_ERROR);
  753. }
  754. break;
  755. case(INPUT_DIFFERENT_SRATES+4):
  756. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  757. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  758. return(DATA_ERROR);
  759. }
  760. break;
  761. case(INPUT_DUPLICATE_SNDS+4):
  762. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  763. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  764. return(DATA_ERROR);
  765. }
  766. break;
  767. case(INPUT_BRKSIZE+4):
  768. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  769. sprintf(errstr,"Cannot read brksize sent from TK\n");
  770. return(DATA_ERROR);
  771. }
  772. if(inbrksize > 0) {
  773. switch(dz->input_data_type) {
  774. case(WORDLIST_ONLY):
  775. break;
  776. case(PITCH_AND_PITCH):
  777. case(PITCH_AND_TRANSPOS):
  778. case(TRANSPOS_AND_TRANSPOS):
  779. dz->tempsize = inbrksize;
  780. break;
  781. case(BRKFILES_ONLY):
  782. case(UNRANGED_BRKFILE_ONLY):
  783. case(DB_BRKFILES_ONLY):
  784. case(ALL_FILES):
  785. case(ANY_NUMBER_OF_ANY_FILES):
  786. if(dz->extrabrkno < 0) {
  787. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  788. return(DATA_ERROR);
  789. }
  790. if(dz->brksize == NULL) {
  791. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  792. return(PROGRAM_ERROR);
  793. }
  794. dz->brksize[dz->extrabrkno] = inbrksize;
  795. break;
  796. default:
  797. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  798. dz->input_data_type);
  799. return(PROGRAM_ERROR);
  800. }
  801. break;
  802. }
  803. break;
  804. case(INPUT_NUMSIZE+4):
  805. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  806. sprintf(errstr,"Cannot read numsize sent from TK\n");
  807. return(DATA_ERROR);
  808. }
  809. break;
  810. case(INPUT_LINECNT+4):
  811. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  812. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  813. return(DATA_ERROR);
  814. }
  815. break;
  816. case(INPUT_ALL_WORDS+4):
  817. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  818. sprintf(errstr,"Cannot read all_words sent from TK\n");
  819. return(DATA_ERROR);
  820. }
  821. break;
  822. case(INPUT_ARATE+4):
  823. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  824. sprintf(errstr,"Cannot read arate sent from TK\n");
  825. return(DATA_ERROR);
  826. }
  827. break;
  828. case(INPUT_FRAMETIME+4):
  829. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  830. sprintf(errstr,"Cannot read frametime sent from TK\n");
  831. return(DATA_ERROR);
  832. }
  833. dz->frametime = (float)dummy;
  834. break;
  835. case(INPUT_WINDOW_SIZE+4):
  836. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  837. sprintf(errstr,"Cannot read window_size sent from TK\n");
  838. return(DATA_ERROR);
  839. }
  840. break;
  841. case(INPUT_NYQUIST+4):
  842. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  843. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  844. return(DATA_ERROR);
  845. }
  846. break;
  847. case(INPUT_DURATION+4):
  848. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  849. sprintf(errstr,"Cannot read duration sent from TK\n");
  850. return(DATA_ERROR);
  851. }
  852. break;
  853. case(INPUT_MINBRK+4):
  854. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  855. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  856. return(DATA_ERROR);
  857. }
  858. break;
  859. case(INPUT_MAXBRK+4):
  860. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  861. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  862. return(DATA_ERROR);
  863. }
  864. break;
  865. case(INPUT_MINNUM+4):
  866. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  867. sprintf(errstr,"Cannot read minnum sent from TK\n");
  868. return(DATA_ERROR);
  869. }
  870. break;
  871. case(INPUT_MAXNUM+4):
  872. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  873. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  874. return(DATA_ERROR);
  875. }
  876. break;
  877. default:
  878. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  879. return(PROGRAM_ERROR);
  880. }
  881. cnt++;
  882. }
  883. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  884. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  885. return(DATA_ERROR);
  886. }
  887. if(true_cnt)
  888. cnt = true_cnt;
  889. *cmdlinecnt = 0;
  890. while(cnt < argc) {
  891. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  892. return(exit_status);
  893. cnt++;
  894. }
  895. return(FINISHED);
  896. }
  897. /********************************* GET_TK_CMDLINE_WORD *********************************/
  898. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  899. {
  900. if(*cmdlinecnt==0) {
  901. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  902. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  903. return(MEMORY_ERROR);
  904. }
  905. } else {
  906. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  907. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  908. return(MEMORY_ERROR);
  909. }
  910. }
  911. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  912. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  913. return(MEMORY_ERROR);
  914. }
  915. strcpy((*cmdline)[*cmdlinecnt],q);
  916. (*cmdlinecnt)++;
  917. return(FINISHED);
  918. }
  919. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  920. int assign_file_data_storage(int infilecnt,dataptr dz)
  921. {
  922. int exit_status;
  923. int no_sndfile_system_files = FALSE;
  924. dz->infilecnt = infilecnt;
  925. if((exit_status = allocate_filespace(dz))<0)
  926. return(exit_status);
  927. if(no_sndfile_system_files)
  928. dz->infilecnt = 0;
  929. return(FINISHED);
  930. }
  931. /************************* redundant functions: to ensure libs compile OK *******************/
  932. int assign_process_logic(dataptr dz)
  933. {
  934. return(FINISHED);
  935. }
  936. void set_legal_infile_structure(dataptr dz)
  937. {}
  938. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  939. {
  940. return(FINISHED);
  941. }
  942. int setup_internal_arrays_and_array_pointers(dataptr dz)
  943. {
  944. return(FINISHED);
  945. }
  946. int establish_bufptrs_and_extra_buffers(dataptr dz)
  947. {
  948. return(FINISHED);
  949. }
  950. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  951. {
  952. return(FINISHED);
  953. }
  954. int read_special_data(char *str,dataptr dz)
  955. {
  956. return(FINISHED);
  957. }
  958. int inner_loop
  959. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  960. {
  961. return(FINISHED);
  962. }
  963. /********************************************************************************************/
  964. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  965. {
  966. if (!strcmp(prog_identifier_from_cmdline,"stretch")) dz->process = SPECTSTR;
  967. else {
  968. fprintf(stderr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  969. return(USAGE_ONLY);
  970. }
  971. return(FINISHED);
  972. }
  973. /******************************** USAGE1 ********************************/
  974. int usage1(void)
  975. {
  976. return(usage2("stretch"));
  977. }
  978. /******************************** USAGE2 ********************************/
  979. int usage2(char *str)
  980. {
  981. if(!strcmp(str,"stretch")) { /* STRETCH */
  982. fprintf(stdout,
  983. "spectstr stretch time infile outfile timestretch d-ratio di-rand\n"
  984. "\n"
  985. "TIME-STRETCHING OF INFILE, SUPPRESSING ARTEFACTS WHEN STRETCH IS > 1.0\n"
  986. "\n"
  987. "TIMESTRETCH may itself vary over time.\n"
  988. "D-RATIO proportion of channels to discohere.\n"
  989. "D-RAND Frequency randomisation of discohered channels.\n");
  990. } else
  991. sprintf(errstr,"Unknown option '%s'\n",str);
  992. return(USAGE_ONLY);
  993. }
  994. int usage3(char *str1,char *str2)
  995. {
  996. fprintf(stderr,"Insufficient parameters on command line.\n");
  997. return(USAGE_ONLY);
  998. }
  999. /************ SETUP_INTERNAL_PARAMS_FOR_TSTRETCH *************/
  1000. int setup_internal_params_for_tstretch(dataptr dz)
  1001. {
  1002. int exit_status;
  1003. if(dz->brksize[TSTR_STRETCH] && (exit_status = force_value_at_zero_time(TSTR_STRETCH,dz))<0)
  1004. return(exit_status);
  1005. dz->param[TSTR_TOTIME] = (double)dz->wlength * dz->frametime;
  1006. /* dur of orig sound source */
  1007. dz->iparam[TSTR_ARRAYSIZE] = POSMIN;
  1008. if((dz->parray[TSTR_PBUF] = (double *)malloc(dz->iparam[TSTR_ARRAYSIZE] * sizeof(double)))==NULL) {
  1009. sprintf(errstr,"INSUFFICIENT MEMORY for timestretch array.\n");
  1010. return(MEMORY_ERROR);
  1011. }
  1012. dz->ptr[TSTR_PEND] = dz->parray[TSTR_PBUF] + dz->iparam[TSTR_ARRAYSIZE];
  1013. if((dz->parray[TSTR_QBUF] = (double *)malloc(dz->iparam[TSTR_ARRAYSIZE] * sizeof(double)))==NULL) {
  1014. sprintf(errstr,"INSUFFICIENT MEMORY for 2nd timestretch array.\n");
  1015. return(MEMORY_ERROR);
  1016. }
  1017. return(FINISHED);
  1018. }
  1019. /********************* CHECK_FOR_ENOUGH_TSTRETCH_BRKPNT_VALS **********************/
  1020. int check_for_enough_tstretch_brkpnt_vals(dataptr dz)
  1021. {
  1022. if(dz->brksize[TSTR_STRETCH] && dz->brksize[TSTR_STRETCH] < 2) {
  1023. sprintf(errstr,"Not enough data in tsretch data file.\n");
  1024. return(DATA_ERROR);
  1025. }
  1026. dz->do_decohere = 1;
  1027. if(dz->param[DISC_RATIO] == 0.0 || dz->param[DISC_RAND] == 0.0)
  1028. dz->do_decohere = 0;
  1029. dz->iparam[DISC_RATIO] = (int)round(dz->param[DISC_RATIO] * dz->clength);
  1030. return(FINISHED);
  1031. }
  1032. /*************************** ALLOCATE_TSTRETCH_BUFFER ****************************/
  1033. int allocate_tstretch_buffer(dataptr dz)
  1034. {
  1035. unsigned int buffersize;
  1036. dz->bptrcnt = 6;
  1037. if((dz->flbufptr = (float **)malloc(dz->bptrcnt * sizeof(float *)))==NULL) {
  1038. sprintf(errstr,"INSUFFICIENT MEMORY for sound buffer pointers.\n");
  1039. return(MEMORY_ERROR);
  1040. }
  1041. buffersize = dz->wanted * BUF_MULTIPLIER;
  1042. dz->buflen = buffersize;
  1043. buffersize *= 2;
  1044. buffersize += dz->wanted;
  1045. if((dz->bigfbuf = (float *)malloc((size_t)(buffersize * sizeof(float))))==NULL) {
  1046. sprintf(errstr,"INSUFFICIENT MEMORY for sound buffers.\n");
  1047. return(MEMORY_ERROR);
  1048. }
  1049. dz->big_fsize = dz->buflen;
  1050. dz->flbufptr[0] = dz->bigfbuf + dz->wanted; /* inbuf */
  1051. dz->flbufptr[1] = dz->flbufptr[0] + dz->big_fsize; /* outbuf & inbufend */
  1052. dz->flbufptr[2] = dz->flbufptr[1] + dz->big_fsize; /* outbufend */
  1053. dz->flbufptr[3] = dz->flbufptr[0]; /* 1st inbuf pointer */
  1054. dz->flbufptr[4] = dz->flbufptr[0] + dz->wanted; /* 2nd inbuf pointer */
  1055. dz->flbufptr[5] = dz->flbufptr[1]; /* outbuf ptr */
  1056. return(FINISHED);
  1057. }
  1058. /********************************** SPECTSTRETCH ***********************************/
  1059. int spectstretch(dataptr dz)
  1060. {
  1061. int exit_status;
  1062. int thatwindow;
  1063. int samps_read;
  1064. if((samps_read = fgetfbufEx(dz->flbufptr[0], dz->big_fsize,dz->ifd[0],0)) < 0) {
  1065. sprintf(errstr,"No data found in input soundfile.\n");
  1066. return(DATA_ERROR);
  1067. }
  1068. if(sloom)
  1069. dz->total_samps_read = samps_read;
  1070. dz->flbufptr[3] = dz->flbufptr[0];
  1071. dz->flbufptr[4] = dz->flbufptr[0] + dz->wanted;
  1072. thatwindow = 0;
  1073. if(dz->brksize[TSTR_STRETCH]==0)
  1074. exit_status = do_constant_timestretch(&thatwindow,dz);
  1075. else
  1076. exit_status = do_timevariable_timestretch(&thatwindow,dz);
  1077. if(exit_status<0)
  1078. return(exit_status);
  1079. if((exit_status = do_timestretching(&thatwindow,dz->ptr[TSTR_PBUF] - dz->parray[TSTR_PBUF],dz))<0)
  1080. return(exit_status);
  1081. if(dz->flbufptr[5] - dz->flbufptr[1] > 0)
  1082. return write_samps(dz->flbufptr[1],dz->flbufptr[5] - dz->flbufptr[1],dz);
  1083. return(FINISHED);
  1084. }
  1085. /******************************* DO_CONSTANT_TIMESTRETCH ****************************
  1086. *
  1087. * Set up array of indices for reading source window values into new
  1088. * windows.
  1089. *
  1090. * (0) Initialise position-buffer pointer and start window.
  1091. * (1) Get first breakpoint pair from brkpoint table.
  1092. * (2) Calculate initial time as whole number of WINDOWS.
  1093. * (3) If time is stretched, output window is SHRUNK relative to input
  1094. * window. Hence val = 1/stretch.
  1095. * (4) Proceed in a loop of all input breakpoint values.
  1096. * (5) Returns if premature end of file encountered.
  1097. */
  1098. int do_constant_timestretch(int *thatwindow,dataptr dz)
  1099. {
  1100. double thiswdur, dcount, dur;
  1101. int count;
  1102. int startwindow = 0;
  1103. dz->ptr[TSTR_PBUF] = dz->parray[TSTR_PBUF];
  1104. thiswdur = 1.0/dz->param[TSTR_STRETCH]; /* 3 */
  1105. dcount = (double)dz->wlength/thiswdur;
  1106. count = round(fabs(dcount));
  1107. dur = (double)dz->wlength/(double)count;
  1108. return divide_time_into_equal_increments(thatwindow,startwindow,dur,count,dz);
  1109. }
  1110. /******************************* DO_TIMEVARIABLE_TIMESTRETCH ****************************
  1111. *
  1112. * Set up array of indices for reading source window values into new
  1113. * windows.
  1114. *
  1115. * (0) Initialise position-buffer pointer and start window.
  1116. * (1) Get first breakpoint pair from brkpoint table.
  1117. * (2) Calculate initial time as whole number of WINDOWS.
  1118. * (3) If time is stretched, output window is SHRUNK relative to input
  1119. * window. Hence val = 1/stretch.
  1120. * (4) Proceed in a loop of all input breakpoint values.
  1121. * (5) Returns if brkpnt times ran off end of source soundfile.
  1122. */
  1123. int do_timevariable_timestretch(int *thatwindow,dataptr dz)
  1124. {
  1125. int exit_status;
  1126. int time0, time1, time2, totaldur;
  1127. double stretch0, stretch1, thiswdur, nextwdur, valdiff, dtime0, dtime1;
  1128. int atend = FALSE;
  1129. int startwindow = 0; /* 0 */
  1130. int timestretch_called = FALSE;
  1131. dz->ptr[TSTR_PBUF] = dz->parray[TSTR_PBUF];
  1132. if((exit_status = get_both_vals_from_brktable(&dtime0,&stretch0,TSTR_STRETCH,dz))<0) /* 1 */
  1133. return(exit_status);
  1134. if(exit_status == FINISHED) {
  1135. sprintf(errstr,"Not enough data in brkfile & not trapped earlier: do_timevariable_timestretch()\n");
  1136. return(PROGRAM_ERROR);
  1137. }
  1138. time0 = round(dtime0/dz->frametime); /* 2 */
  1139. thiswdur = 1.0/stretch0; /* 3 */
  1140. while((exit_status = get_both_vals_from_brktable(&dtime1,&stretch1,TSTR_STRETCH,dz))==CONTINUE) {/* 4 */
  1141. nextwdur = 1.0/stretch1;
  1142. if((time1 = round(dtime1/dz->frametime)) > dz->wlength) {
  1143. time2 = time1; /* 5 */
  1144. time1 = round(dz->param[TSTR_TOTIME]/dz->frametime);
  1145. valdiff = nextwdur - thiswdur;
  1146. valdiff *= (double)(time1 - time0)/(double)(time2 - time0);
  1147. nextwdur = thiswdur + valdiff;
  1148. atend = TRUE;
  1149. }
  1150. totaldur = time1 - time0;
  1151. timestretch_called = TRUE;
  1152. if((exit_status = timestretch_this_segment(thatwindow,startwindow,thiswdur,nextwdur,totaldur,dz))<0)
  1153. return(exit_status);
  1154. startwindow += totaldur;
  1155. thiswdur = nextwdur;
  1156. time0 = time1;
  1157. if(atend)
  1158. break;
  1159. }
  1160. if(timestretch_called == FALSE) {
  1161. sprintf(errstr,"Not enough data in brkfile & not trapped earlier: do_timevariable_timestretch()\n");
  1162. return(PROGRAM_ERROR);
  1163. }
  1164. return(FINISHED);
  1165. }
  1166. /*************************** DO_TIMESTRETCHING ********************************
  1167. *
  1168. * Read/interpolate source analysis windows.
  1169. *
  1170. * (1) initialise the position-buffer pointer. NB we don't use pbufptr as
  1171. * this is (?) still marking the current position in the output buffer.
  1172. * (2) For each entry in the position-array.
  1173. * (3) get the absolute position.
  1174. * (4) The window to intepolate FROM is this truncated
  1175. * e.g. position 3.2 translates to window 3.
  1176. * (5) Is this is a move on from the current window position? How far?
  1177. * (6) If we're in the final window, set the 'atend' flag.
  1178. * (7) If we need to move on, call advance-windows and set up a new PAIR of
  1179. * input windows.
  1180. * (8) Get Interpolation time-fraction.
  1181. * (9) Get output values by interpolation between input values.
  1182. * (10) Write a complete out-windowbuf to output file.
  1183. * (11) Give on-screen user information.
  1184. */
  1185. int do_timestretching(int *thatwindow,int count,dataptr dz)
  1186. {
  1187. int exit_status;
  1188. double amp0, amp1, phas0, phas1;
  1189. int vc;
  1190. int n, thiswindow, step;
  1191. int atend = FALSE;
  1192. double here, frac;
  1193. double *p = dz->parray[TSTR_PBUF]; /* 1 */
  1194. for(n=0;n<count;n++) { /* 2 */
  1195. here = *p++; /* 3 */
  1196. thiswindow = (int)here; /* TRUNCATE */ /* 4 */
  1197. step = thiswindow - *thatwindow; /* 5 */
  1198. if(thiswindow == dz->wlength-1) /* 6 */
  1199. atend = TRUE;
  1200. if(step) {
  1201. if((exit_status = advance_along_input_windows(step,atend,dz))<0) /* 7 */
  1202. return(exit_status);
  1203. }
  1204. frac = here - (double)thiswindow; /* 8 */
  1205. for(vc = 0; vc < dz->wanted; vc += 2) {
  1206. amp0 = dz->flbufptr[3][AMPP]; /* 9 */
  1207. phas0 = dz->flbufptr[3][FREQ];
  1208. amp1 = dz->flbufptr[4][AMPP];
  1209. phas1 = dz->flbufptr[4][FREQ];
  1210. dz->flbufptr[5][AMPP] = (float)(amp0 + ((amp1 - amp0) * frac));
  1211. dz->flbufptr[5][FREQ] = (float)(phas0 + ((phas1 - phas0) * frac));
  1212. }
  1213. if(dz->do_decohere) {
  1214. if((exit_status = decohere(dz->flbufptr[5],dz))<0)
  1215. return(exit_status);
  1216. }
  1217. if((dz->flbufptr[5] += dz->wanted) >= dz->flbufptr[2]) {
  1218. if((exit_status = write_exact_samps(dz->flbufptr[1],dz->big_fsize,dz))<0)
  1219. return(exit_status);
  1220. dz->flbufptr[5] = dz->flbufptr[1];
  1221. }
  1222. *thatwindow = thiswindow;
  1223. }
  1224. return(FINISHED);
  1225. }
  1226. /**************************** DIVIDE_TIME_INTO_EQUAL_INCREMENTS *****************************
  1227. *
  1228. * all time intervals are equal. Divide up total time thus.
  1229. */
  1230. int divide_time_into_equal_increments(int *thatwindow,int startwindow,double dur,int count,dataptr dz)
  1231. {
  1232. int exit_status;
  1233. int n, remnant;
  1234. int end = dz->ptr[TSTR_PEND] - dz->ptr[TSTR_PBUF];
  1235. int start = 0;
  1236. while(count >= end) {
  1237. for(n = start; n < end; n++)
  1238. *(dz->ptr[TSTR_PBUF])++ = (dur * (double)n) + (double)startwindow;
  1239. if((exit_status = do_timestretching(thatwindow,dz->iparam[TSTR_ARRAYSIZE],dz))<0)
  1240. return(exit_status);
  1241. dz->ptr[TSTR_PBUF] = dz->parray[TSTR_PBUF];
  1242. start = end;
  1243. end += dz->iparam[TSTR_ARRAYSIZE];
  1244. }
  1245. if((remnant = count - start)>0) {
  1246. for(n=start;n<count;n++)
  1247. *(dz->ptr[TSTR_PBUF])++ = (dur * (double)n) + (double)startwindow;
  1248. }
  1249. return(FINISHED);
  1250. }
  1251. /**************************** GET_BOTH_VALS_FROM_BRKTABLE ****************************/
  1252. int get_both_vals_from_brktable(double *thistime,double *thisstretch,int brktab_no,dataptr dz)
  1253. {
  1254. double *brkend = dz->brk[brktab_no] + (dz->brksize[brktab_no] * 2);
  1255. if(dz->brkptr[brktab_no]>=brkend)
  1256. return(FINISHED);
  1257. *thistime = *(dz->brkptr[brktab_no])++;
  1258. if(dz->brkptr[brktab_no]>=brkend) {
  1259. sprintf(errstr,"Anomaly in get_both_vals_from_brktable().\n");
  1260. return(PROGRAM_ERROR);
  1261. }
  1262. *thisstretch = *(dz->brkptr[brktab_no])++;
  1263. return(CONTINUE);
  1264. }
  1265. /************************** TIMESTRETCH_THIS_SEGMENT *****************************
  1266. *
  1267. * Takes a group of input windows, counts number of output windows
  1268. * corresponding to this buffer, and sets up, in pbuff, array(s) of values
  1269. * which are the positions in the input array corresponding to the output
  1270. * array positions.
  1271. * (1) If there is (almost) no change in duration of segments, calculates
  1272. * times on simple additive basis.
  1273. * (2) Otherwise, uses exponential formula.
  1274. * (3) If NOT passed a negative number (i.e. flagged), the sequence of time
  1275. * intervals is reversed.
  1276. */
  1277. int timestretch_this_segment(int *thatwindow,int startwindow,double thiswdur,double nextwdur,int totaldur,dataptr dz)
  1278. {
  1279. int stretch_decreasing = TRUE;
  1280. int count;
  1281. double dur, dcount = calculate_number_of_output_windows(thiswdur,nextwdur,totaldur);
  1282. double param0, param1, param2;
  1283. if(dcount < 0.0)
  1284. stretch_decreasing = FALSE;
  1285. count = round(fabs(dcount));
  1286. if(fabs(nextwdur - thiswdur)<=FLTERR) { /* 1 */
  1287. dur = (double)totaldur/(double)count;
  1288. return divide_time_into_equal_increments(thatwindow,startwindow,dur,count,dz);
  1289. }
  1290. param0 = nextwdur - thiswdur; /* 2 */
  1291. param1 = param0/(double)totaldur;
  1292. param2 = thiswdur * (double)totaldur;
  1293. if(stretch_decreasing==TRUE) /* 3 */
  1294. return calc_position_output_wdws_relative_to_input_wdws_for_decreasing_stretch
  1295. (thatwindow,startwindow,count,totaldur,param0,param1,param2,dz);
  1296. else
  1297. return calc_position_output_wdws_relative_to_input_wdws_for_increasing_stretch
  1298. (thatwindow,startwindow,count,param0,param1,param2,dz);
  1299. }
  1300. /*************************** ADVANCE_ALONG_INPUT_WINDOWS ****************************
  1301. *
  1302. * Advance window frame in input.
  1303. * (1) If got to end of data... Advanve ONE LESS than the distance
  1304. * (wdw_to_advance) from last window-pair.
  1305. * (2) Else, advance by cnt windows.
  1306. * (3) If at end of buffer, copy THIS window to start of whole buffer,
  1307. * (4) And read more data in AFTER that (dz->wanted samps from start).
  1308. * (6) If this is the last window in the source file, there is no other
  1309. * window to interpolate to, so set last window to same as this.
  1310. */
  1311. int advance_along_input_windows(int wdw_to_advance,int atend,dataptr dz)
  1312. {
  1313. int n, count;
  1314. int samps_read;
  1315. if(atend) /* 1 */
  1316. count = wdw_to_advance-1;
  1317. else /* 2 */
  1318. count = wdw_to_advance;
  1319. for(n=0;n<count;n++) {
  1320. dz->flbufptr[3] = dz->flbufptr[4]; /* ADVANCE LASTWINDOW TO THISWINDOW */
  1321. if((dz->flbufptr[4] += dz->wanted) > dz->flbufptr[1]) { /* ADVANCE THISWINDOW TO NEXT */
  1322. memmove((char *)dz->bigfbuf,(char *)dz->flbufptr[3],dz->wanted * sizeof(float));
  1323. dz->flbufptr[3] = dz->bigfbuf; /* 3 */
  1324. dz->flbufptr[4] = dz->flbufptr[0]; /* 4 */
  1325. if((samps_read = fgetfbufEx(dz->flbufptr[4],dz->big_fsize,dz->ifd[0],0)) < dz->wanted) {
  1326. if(n <= count-2) {
  1327. sprintf(errstr,"Program miscounted windows: anomaly 1 at EOF? : advance_along_input_windows()\n");
  1328. return(PROGRAM_ERROR);
  1329. }
  1330. if(samps_read < 0) {
  1331. sprintf(errstr,"Program miscounted windows: anomaly 2 at EOF? : advance_along_input_windows()\n");
  1332. return(PROGRAM_ERROR);
  1333. }
  1334. return(FINISHED);
  1335. }
  1336. if(sloom)
  1337. dz->total_samps_read += samps_read;
  1338. }
  1339. }
  1340. if(atend) /* 6 */
  1341. dz->flbufptr[4] = dz->flbufptr[3];
  1342. return(CONTINUE);
  1343. }
  1344. /*************************** CALCULATE_NUMBER_OF_OUTPUT_WINDOWS ***************************
  1345. *
  1346. * Given a sequence of events of varying duration, where initial and
  1347. * final durations are known, together with start and end times of the
  1348. * total sequence, this function calculates the total number of events.
  1349. *
  1350. * NB
  1351. * (1) Where the segment duration is increading, log(startwdur/edndur) is -ve,
  1352. * so the returned count is -ve.
  1353. * (2) Where segment duration is NOT changing, log(startwdur/endwdur), and hence dcount, would be zero.
  1354. * This situation is trapped by first checking for (approx) equality of startwdur and endwdur
  1355. * and calculating the count in simpler manner.
  1356. */
  1357. double calculate_number_of_output_windows(double startwdur,double endwdur,int totaldur)
  1358. {
  1359. double durdiff, dcount;
  1360. if(flteq((durdiff = endwdur - startwdur),0.0)) {
  1361. dcount = (double)totaldur/endwdur;
  1362. return(dcount);
  1363. }
  1364. dcount = startwdur/endwdur;
  1365. dcount = log(dcount);
  1366. dcount *= (double)totaldur/durdiff;
  1367. return(dcount);
  1368. }
  1369. /********* CALC_POSITION_OUTPUT_WDWS_RELATIVE_TO_INPUT_WDWS_FOR_DECREASING_STRETCH ************
  1370. *
  1371. * THE ARRAY OF positions has to be retrograded, but if we have more than
  1372. * a single output-arrayfull of position values, we must start calculating
  1373. * the output position array from the last input position, then invert those
  1374. * positions so they are first positions, and so on!!!
  1375. * (0) As the array is to be filled backwards, start calculating positions
  1376. * from end of input. So end of first pass = end of input (= count).
  1377. * (1) Find how many locations remain in output-position buffer.
  1378. * (2) Start of first pass is this no of positions before end.
  1379. * (3) If start is < 0 this means that all the positions in the current input
  1380. * pass will fit in the output buffer in its current state, so we skip the
  1381. * loop and go to (10), Otherwise...
  1382. * (4) Mark the address in the output buffer where writing-values begins.
  1383. * (5) Store in output buffer, the positions RELATIVE to start of this segment
  1384. * of input values (i.e. relative to ZERO).
  1385. * (6) Retrograde this time-interval set.
  1386. * (7) Increment these relative values by startwindow, to give absolute
  1387. * position values.
  1388. * (8) Do the output, and reinitialise the output buffer pointer to start
  1389. * of buffer. Reset new input-block end to START of previous block
  1390. * (we're working backwards).
  1391. * (9) Decrement start of block by size of output array.
  1392. * (10) If either we did not enter the loop OR we have some input values
  1393. * left on leaving the principle loop, calcuate output positions of
  1394. * these items, and store in the output buffer (which will be flushed
  1395. * either by next call to timestretch_this_segment() or, at end, by flushbuf()).
  1396. */
  1397. int calc_position_output_wdws_relative_to_input_wdws_for_decreasing_stretch
  1398. (int *thatwindow,int startwindow,int count,int totaldur,double param0,double param1,double param2,dataptr dz)
  1399. {
  1400. int exit_status;
  1401. int n, start, end = count; /* 0 */
  1402. double *p, *startptr;
  1403. int tofill = dz->ptr[TSTR_PEND] - dz->ptr[TSTR_PBUF]; /* 1 */
  1404. start = count - tofill; /* 2 */
  1405. while(start>=0) { /* 3 */
  1406. startptr = dz->ptr[TSTR_PBUF]; /* 4 */
  1407. for(n=start;n<end;n++) /* 5 */
  1408. *(dz->ptr[TSTR_PBUF])++ = calculate_position(n,param0,param1,param2);
  1409. /* 6 */
  1410. if((exit_status = retrograde_sequence_of_time_intervals(totaldur - start,end - start,startptr,dz))<0)
  1411. return(exit_status);
  1412. for(p = startptr;p<dz->ptr[TSTR_PEND];p++)
  1413. *p += (double)startwindow; /* 7 */
  1414. if((exit_status = do_timestretching(thatwindow,dz->iparam[TSTR_ARRAYSIZE],dz))<0)
  1415. return(exit_status);
  1416. dz->ptr[TSTR_PBUF] = dz->parray[TSTR_PBUF]; /* 8 */
  1417. end = start;
  1418. start -= dz->iparam[TSTR_ARRAYSIZE]; /* 9 */
  1419. }
  1420. if(end) { /* 10 */
  1421. startptr = dz->ptr[TSTR_PBUF];
  1422. for(n=0;n<end;n++)
  1423. *(dz->ptr[TSTR_PBUF])++ = calculate_position(n,param0,param1,param2);
  1424. if((exit_status = retrograde_sequence_of_time_intervals(totaldur,end,startptr,dz))<0)
  1425. return(exit_status);
  1426. for(p = startptr;p<dz->ptr[TSTR_PBUF];p++)
  1427. *p += (double)startwindow;
  1428. }
  1429. return(FINISHED);
  1430. }
  1431. /********* CALC_POSITION_OUTPUT_WDWS_RELATIVE_TO_INPUT_WDWS_FOR_INCREASING_STRETCH ************
  1432. *
  1433. * Find positions of output samples relative to input samples, buffer
  1434. * by buffer.
  1435. */
  1436. int calc_position_output_wdws_relative_to_input_wdws_for_increasing_stretch
  1437. (int *thatwindow,int startwindow,int count,double param0,double param1,double param2,dataptr dz)
  1438. {
  1439. int exit_status;
  1440. int n;
  1441. int start = 0;
  1442. int end = dz->ptr[TSTR_PEND] - dz->ptr[TSTR_PBUF];
  1443. while(count>=end) {
  1444. for(n=start;n<end;n++)
  1445. *(dz->ptr[TSTR_PBUF])++ = calculate_position(n,param0,param1,param2) + (double)startwindow;
  1446. if((exit_status = do_timestretching(thatwindow,dz->iparam[TSTR_ARRAYSIZE],dz))<0)
  1447. return(exit_status);
  1448. dz->ptr[TSTR_PBUF] = dz->parray[TSTR_PBUF];
  1449. start = end;
  1450. end += dz->iparam[TSTR_ARRAYSIZE];
  1451. }
  1452. if(count-start) {
  1453. for(n=start;n<count;n++)
  1454. *(dz->ptr[TSTR_PBUF])++ = calculate_position(n,param0,param1,param2) + (double)startwindow;
  1455. }
  1456. return(FINISHED);
  1457. }
  1458. /*************************** CALCULATE_POSITION ****************************
  1459. *
  1460. * Do the position calculation using the exponential formula.
  1461. */
  1462. double calculate_position(int x,double param0,double param1,double param2)
  1463. {
  1464. double k;
  1465. k = param1;
  1466. k *= (double)x;
  1467. k = exp(k);
  1468. k *= param2;
  1469. k -= param2;
  1470. return(k/(param0));
  1471. }
  1472. /*************************** RETROGRADE_SEQUENCE_OF_TIME_INTERVALS **************************
  1473. *
  1474. * Accepts a sequence of times, starting in address startptr,
  1475. * and retrogrades the sequence of time-intervals, storing the
  1476. * results back in startptr onwards.
  1477. */
  1478. int retrograde_sequence_of_time_intervals(int endtime,int count,double *startptr,dataptr dz)
  1479. {
  1480. double newtime, lasttime, tsize;
  1481. int n;
  1482. double *p = startptr;
  1483. dz->ptr[TSTR_QBUF] = dz->parray[TSTR_QBUF] + (count-1);
  1484. newtime = endtime;
  1485. for(n=0;n<(count-1);n++) {
  1486. lasttime = *p++;
  1487. tsize = *p - lasttime;
  1488. newtime -= tsize;
  1489. *dz->ptr[TSTR_QBUF]-- = newtime;
  1490. }
  1491. if(dz->ptr[TSTR_QBUF]!=dz->parray[TSTR_QBUF]) {
  1492. sprintf(errstr,"counting problem: retrograde_sequence_of_time_intervals()\n");
  1493. return(PROGRAM_ERROR);
  1494. }
  1495. *dz->ptr[TSTR_QBUF] = *p; /* put starttime at start of intervals inverted array */
  1496. p = startptr;
  1497. for(n=0;n<count;n++)
  1498. *p++ = *dz->ptr[TSTR_QBUF]++;
  1499. return(FINISHED);
  1500. }
  1501. /******************************************* DECOHERE ****************************************/
  1502. int decohere(float *fbuf,dataptr dz)
  1503. {
  1504. int *store = dz->iparray[0];
  1505. int cc, vc, j, k;
  1506. float ampj, ampk;
  1507. double randval, chanfrq, frq;
  1508. for(cc = 0; cc < dz->clength;cc++)
  1509. store[cc] = cc;
  1510. // Sort channel numbers into order of ascending loudness
  1511. for(k = 0; k < dz->clength - 1; k++) {
  1512. vc = store[k] * 2; // vc is index of amps in buffer, cc is count of chans (chan = amp&frq vals)
  1513. ampk = fbuf[AMPP]; // AMPP = vc
  1514. for(j = k+1; j < dz->clength; j++) {
  1515. vc = store[j] * 2;
  1516. ampj = fbuf[AMPP];
  1517. if(ampj < ampk) { // If item higher up array (ampj) has lower amp than item lower down array (ampk)
  1518. cc = store[k]; // Swap the stored channel numbers
  1519. store[k] = store[j];
  1520. store[j] = cc;
  1521. ampk = ampj; // And reset amplitude ampk to the lower amp
  1522. }
  1523. }
  1524. }
  1525. // Randomise frqs in lower amplitude chans
  1526. for(k = 0; k < dz->iparam[DISC_RATIO]; k++) {
  1527. cc = store[k];
  1528. frq = (double)cc * dz->chwidth;
  1529. randval = ((drand48() * 2.0) - 1.0)/2.0; // Range -1/2 to +1/2
  1530. randval *= dz->param[DISC_RAND]; // Range -DISC_RAND/2 to +DISC_RAND/2
  1531. chanfrq = frq + randval;
  1532. if(chanfrq < PITCHZERO || chanfrq >= dz->nyquist) // In lowest channel, avoid v. low or -ve frqs (chan centre is at zero)
  1533. chanfrq = frq - randval; // In highest channel, avoid frq beyond nyquist ((chan centre at nyquist)
  1534. vc = cc * 2;
  1535. fbuf[FREQ] = (float)chanfrq; // FREQ = vc+1
  1536. }
  1537. return FINISHED;
  1538. }