repeater.c 87 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994
  1. /*
  2. * Copyright (c) 1983-2013 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. // _cdprogs\repeater repeater 3 alan_bellydancefc.wav test.wav repeater2.txt 8 .66 .66 -r2 -p.5
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <structures.h>
  25. #include <tkglobals.h>
  26. #include <pnames.h>
  27. #include <filetype.h>
  28. #include <processno.h>
  29. #include <modeno.h>
  30. #include <logic.h>
  31. #include <globcon.h>
  32. #include <cdpmain.h>
  33. #include <math.h>
  34. #include <mixxcon.h>
  35. #include <osbind.h>
  36. #include <standalone.h>
  37. #include <science.h>
  38. #include <ctype.h>
  39. #include <sfsys.h>
  40. #include <string.h>
  41. #include <srates.h>
  42. #define SAFETY 64
  43. #define maxmaxbuf total_windows
  44. #define envwindowlen ringsize
  45. #define arraysize rampbrksize
  46. #define REPCLIP 0.95 // level to normalise to
  47. #define REPMINDEL 0.02 // minimum delay to produce oscillaor effect
  48. #ifdef unix
  49. #define round(x) lround((x))
  50. #endif
  51. char errstr[2400];
  52. int anal_infiles = 1;
  53. int sloom = 0;
  54. int sloombatch = 0;
  55. const char* cdp_version = "6.1.0";
  56. //CDP LIB REPLACEMENTS
  57. static int setup_repeater_application(dataptr dz);
  58. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  59. static int parse_infile_and_check_type(char **cmdline,dataptr dz);
  60. static int setup_repeater_param_ranges_and_defaults(dataptr dz);
  61. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz);
  62. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  63. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  64. static int establish_application(dataptr dz);
  65. static int initialise_vflags(dataptr dz);
  66. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  67. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  68. static int mark_parameter_types(dataptr dz,aplptr ap);
  69. static int assign_file_data_storage(int infilecnt,dataptr dz);
  70. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  71. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  72. static int get_the_mode_from_cmdline(char *str,dataptr dz);
  73. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  74. static int create_repeater_sndbufs(double maxseglen, double maxovlp, dataptr dz);
  75. static int handle_the_special_data(char *str,double *maxseglen,double *maxovlp,dataptr dz);
  76. static int repeater(dataptr dz);
  77. static int setup_repeater_param_ranges_and_defaults(dataptr dz);
  78. static int setup_repeater_application(dataptr dz);
  79. static int write_and_reset_obuf(int samps_to_write,int *obufpos,dataptr dz);
  80. static int reset_ibuf_and_read(int *ibufpos,dataptr dz) ;
  81. static int normalise_buffer(int samplen,dataptr dz);
  82. static int calc_output_dur(int *dursamps,dataptr dz);
  83. /**************************************** MAIN *********************************************/
  84. int main(int argc,char *argv[])
  85. {
  86. int exit_status;
  87. dataptr dz = NULL;
  88. char **cmdline;
  89. int cmdlinecnt;
  90. int n;
  91. double maxseglen, maxovlp;
  92. aplptr ap;
  93. int is_launched = FALSE;
  94. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  95. fprintf(stdout,"%s\n",cdp_version);
  96. fflush(stdout);
  97. return 0;
  98. }
  99. /* CHECK FOR SOUNDLOOM */
  100. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  101. sloom = 0;
  102. sloombatch = 1;
  103. }
  104. if(sflinit("cdp")){
  105. sfperror("cdp: initialisation\n");
  106. return(FAILED);
  107. }
  108. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  109. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  110. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  111. return(FAILED);
  112. }
  113. if(!sloom) {
  114. if(argc == 1) {
  115. usage1();
  116. return(FAILED);
  117. } else if(argc == 2) {
  118. usage2(argv[1]);
  119. return(FAILED);
  120. }
  121. }
  122. if(!sloom) {
  123. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  124. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  125. return(FAILED);
  126. }
  127. cmdline = argv;
  128. cmdlinecnt = argc;
  129. if((get_the_process_no(argv[0],dz))<0)
  130. return(FAILED);
  131. cmdline++;
  132. cmdlinecnt--;
  133. dz->maxmode = 3;
  134. if((exit_status = get_the_mode_from_cmdline(cmdline[0],dz))<0) {
  135. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  136. return(exit_status);
  137. }
  138. cmdline++;
  139. cmdlinecnt--;
  140. // setup_particular_application =
  141. if((exit_status = setup_repeater_application(dz))<0) {
  142. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  143. return(FAILED);
  144. }
  145. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  146. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  147. return(FAILED);
  148. }
  149. } else {
  150. //parse_TK_data() =
  151. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  152. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  153. return(exit_status);
  154. }
  155. }
  156. ap = dz->application;
  157. // parse_infile_and_hone_type() =
  158. if((exit_status = parse_infile_and_check_type(cmdline,dz))<0) {
  159. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  160. return(FAILED);
  161. }
  162. // setup_param_ranges_and_defaults() =
  163. if((exit_status = setup_repeater_param_ranges_and_defaults(dz))<0) {
  164. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  165. return(FAILED);
  166. }
  167. // open_first_infile CDP LIB
  168. if((exit_status = open_first_infile(cmdline[0],dz))<0) {
  169. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  170. return(FAILED);
  171. }
  172. cmdlinecnt--;
  173. cmdline++;
  174. // handle_extra_infiles() : redundant
  175. // handle_outfile() =
  176. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,dz))<0) {
  177. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  178. return(FAILED);
  179. }
  180. // handle_formants() redundant
  181. // handle_formant_quiksearch() redundant
  182. // handle_special_data() =
  183. if((exit_status = handle_the_special_data(cmdline[0],&maxseglen,&maxovlp,dz))<0) {
  184. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  185. return(FAILED);
  186. }
  187. cmdlinecnt--;
  188. cmdline++;
  189. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  190. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  191. return(FAILED);
  192. }
  193. // check_param_validity_and_consistency() redundant
  194. is_launched = TRUE;
  195. dz->bufcnt = 7;
  196. if((dz->sampbuf = (float **)malloc(sizeof(float *) * (dz->bufcnt+1)))==NULL) {
  197. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffers.\n");
  198. return(MEMORY_ERROR);
  199. }
  200. if((dz->sbufptr = (float **)malloc(sizeof(float *) * dz->bufcnt))==NULL) {
  201. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffer pointers.\n");
  202. return(MEMORY_ERROR);
  203. }
  204. for(n = 0;n <dz->bufcnt; n++)
  205. dz->sampbuf[n] = dz->sbufptr[n] = (float *)0;
  206. dz->sampbuf[n] = (float *)0;
  207. // create_sndbufs() =
  208. if((exit_status = create_repeater_sndbufs(maxseglen,maxovlp,dz))<0) { // CDP LIB
  209. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  210. return(FAILED);
  211. }
  212. //param_preprocess() redundant
  213. //spec_process_file =
  214. if((exit_status = repeater(dz))<0) {
  215. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  216. return(FAILED);
  217. }
  218. if((exit_status = complete_output(dz))<0) { // CDP LIB
  219. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  220. return(FAILED);
  221. }
  222. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  223. free(dz);
  224. return(SUCCEEDED);
  225. }
  226. /**********************************************
  227. REPLACED CDP LIB FUNCTIONS
  228. **********************************************/
  229. /****************************** SET_PARAM_DATA *********************************/
  230. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  231. {
  232. ap->special_data = (char)special_data;
  233. ap->param_cnt = (char)paramcnt;
  234. ap->max_param_cnt = (char)maxparamcnt;
  235. if(ap->max_param_cnt>0) {
  236. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  237. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  238. return(MEMORY_ERROR);
  239. }
  240. strcpy(ap->param_list,paramlist);
  241. }
  242. return(FINISHED);
  243. }
  244. /****************************** SET_VFLGS *********************************/
  245. int set_vflgs
  246. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  247. {
  248. ap->option_cnt = (char) optcnt; /*RWD added cast */
  249. if(optcnt) {
  250. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  251. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  252. return(MEMORY_ERROR);
  253. }
  254. strcpy(ap->option_list,optlist);
  255. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  256. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  257. return(MEMORY_ERROR);
  258. }
  259. strcpy(ap->option_flags,optflags);
  260. }
  261. ap->vflag_cnt = (char) vflagcnt;
  262. ap->variant_param_cnt = (char) vparamcnt;
  263. if(vflagcnt) {
  264. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  265. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  266. return(MEMORY_ERROR);
  267. }
  268. strcpy(ap->variant_list,varlist);
  269. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  270. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  271. return(MEMORY_ERROR);
  272. }
  273. strcpy(ap->variant_flags,varflags);
  274. }
  275. return(FINISHED);
  276. }
  277. /***************************** APPLICATION_INIT **************************/
  278. int application_init(dataptr dz)
  279. {
  280. int exit_status;
  281. int storage_cnt;
  282. int tipc, brkcnt;
  283. aplptr ap = dz->application;
  284. if(ap->vflag_cnt>0)
  285. initialise_vflags(dz);
  286. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  287. ap->total_input_param_cnt = (char)tipc;
  288. if(tipc>0) {
  289. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  290. return(exit_status);
  291. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  292. return(exit_status);
  293. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  294. return(exit_status);
  295. }
  296. brkcnt = tipc;
  297. //THERE ARE NO INPUTFILE brktables USED IN THIS PROCESS
  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. //establish_bufptrs_and_extra_buffers():
  313. return(FINISHED);
  314. }
  315. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  316. /* RWD mallo changed to calloc; helps debug verison run as release! */
  317. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  318. {
  319. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  320. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  321. return(MEMORY_ERROR);
  322. }
  323. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  324. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  325. return(MEMORY_ERROR);
  326. }
  327. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  328. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  329. return(MEMORY_ERROR);
  330. }
  331. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  332. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  333. return(MEMORY_ERROR);
  334. }
  335. return(FINISHED);
  336. }
  337. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  338. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  339. {
  340. int n;
  341. for(n=0;n<storage_cnt;n++) {
  342. dz->is_int[n] = (char)0;
  343. dz->no_brk[n] = (char)0;
  344. }
  345. return(FINISHED);
  346. }
  347. /***************************** MARK_PARAMETER_TYPES **************************/
  348. int mark_parameter_types(dataptr dz,aplptr ap)
  349. {
  350. int n, m; /* PARAMS */
  351. for(n=0;n<ap->max_param_cnt;n++) {
  352. switch(ap->param_list[n]) {
  353. case('0'): break; /* dz->is_active[n] = 0 is default */
  354. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  355. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  356. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  357. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  358. default:
  359. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  360. return(PROGRAM_ERROR);
  361. }
  362. } /* OPTIONS */
  363. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  364. switch(ap->option_list[n]) {
  365. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  366. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  367. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  368. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  369. default:
  370. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  371. return(PROGRAM_ERROR);
  372. }
  373. } /* VARIANTS */
  374. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  375. switch(ap->variant_list[n]) {
  376. case('0'): break;
  377. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  378. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  379. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  380. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  381. default:
  382. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  383. return(PROGRAM_ERROR);
  384. }
  385. } /* INTERNAL */
  386. for(n=0,
  387. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  388. switch(ap->internal_param_list[n]) {
  389. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  390. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  391. case('d'): dz->no_brk[m] = (char)1; break;
  392. default:
  393. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  394. return(PROGRAM_ERROR);
  395. }
  396. }
  397. return(FINISHED);
  398. }
  399. /************************ HANDLE_THE_OUTFILE *********************/
  400. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz)
  401. {
  402. int exit_status;
  403. char *filename = (*cmdline)[0];
  404. if(filename[0]=='-' && filename[1]=='f') {
  405. dz->floatsam_output = 1;
  406. dz->true_outfile_stype = SAMP_FLOAT;
  407. filename+= 2;
  408. }
  409. if(!sloom) {
  410. if(file_has_invalid_startchar(filename) || value_is_numeric(filename)) {
  411. sprintf(errstr,"Outfile name %s has invalid start character(s) or looks too much like a number.\n",filename);
  412. return(DATA_ERROR);
  413. }
  414. }
  415. strcpy(dz->outfilename,filename);
  416. if((exit_status = create_sized_outfile(filename,dz))<0)
  417. return(exit_status);
  418. (*cmdline)++;
  419. (*cmdlinecnt)--;
  420. return(FINISHED);
  421. }
  422. /***************************** ESTABLISH_APPLICATION **************************/
  423. int establish_application(dataptr dz)
  424. {
  425. aplptr ap;
  426. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  427. sprintf(errstr,"establish_application()\n");
  428. return(MEMORY_ERROR);
  429. }
  430. ap = dz->application;
  431. memset((char *)ap,0,sizeof(struct applic));
  432. return(FINISHED);
  433. }
  434. /************************* INITIALISE_VFLAGS *************************/
  435. int initialise_vflags(dataptr dz)
  436. {
  437. int n;
  438. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  439. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  440. return(MEMORY_ERROR);
  441. }
  442. for(n=0;n<dz->application->vflag_cnt;n++)
  443. dz->vflag[n] = FALSE;
  444. return FINISHED;
  445. }
  446. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  447. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  448. {
  449. int n;
  450. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  451. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  452. return(MEMORY_ERROR);
  453. }
  454. for(n=0;n<tipc;n++)
  455. ap->default_val[n] = 0.0;
  456. return(FINISHED);
  457. }
  458. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  459. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  460. {
  461. int n;
  462. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  463. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  464. return(MEMORY_ERROR);
  465. }
  466. for(n=0;n<tipc;n++)
  467. dz->is_active[n] = (char)0;
  468. return(FINISHED);
  469. }
  470. /************************* SETUP_REPEATER_APPLICATION *******************/
  471. int setup_repeater_application(dataptr dz)
  472. {
  473. int exit_status;
  474. aplptr ap;
  475. if((exit_status = establish_application(dz))<0) // GLOBAL
  476. return(FAILED);
  477. ap = dz->application;
  478. // SEE parstruct FOR EXPLANATION of next 2 functions
  479. if(dz->mode < 2)
  480. exit_status = set_param_data(ap,REPEATDATA,3,0,"000");
  481. else
  482. exit_status = set_param_data(ap,REPEATDATA,3,3,"DDD");
  483. if(exit_status <0)
  484. return(FAILED);
  485. if((exit_status = set_vflgs(ap,"rp",3,"DDi","",0,0,""))<0)
  486. return(FAILED);
  487. // set_legal_infile_structure -->
  488. dz->has_otherfile = FALSE;
  489. // assign_process_logic -->
  490. dz->input_data_type = SNDFILES_ONLY;
  491. dz->process_type = UNEQUAL_SNDFILE;
  492. dz->outfiletype = SNDFILE_OUT;
  493. return application_init(dz); //GLOBAL
  494. }
  495. /************************* PARSE_INFILE_AND_CHECK_TYPE *******************/
  496. int parse_infile_and_check_type(char **cmdline,dataptr dz)
  497. {
  498. int exit_status;
  499. infileptr infile_info;
  500. if(!sloom) {
  501. if((infile_info = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  502. sprintf(errstr,"INSUFFICIENT MEMORY for infile structure to test file data.");
  503. return(MEMORY_ERROR);
  504. } else if((exit_status = cdparse(cmdline[0],infile_info))<0) {
  505. sprintf(errstr,"Failed to parse input file %s\n",cmdline[0]);
  506. return(PROGRAM_ERROR);
  507. } else if(infile_info->filetype != SNDFILE) {
  508. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  509. return(DATA_ERROR);
  510. } else if((exit_status = copy_parse_info_to_main_structure(infile_info,dz))<0) {
  511. sprintf(errstr,"Failed to copy file parsing information\n");
  512. return(PROGRAM_ERROR);
  513. }
  514. free(infile_info);
  515. }
  516. return(FINISHED);
  517. }
  518. /************************* SETUP_REPEATER_PARAM_RANGES_AND_DEFAULTS *******************/
  519. int setup_repeater_param_ranges_and_defaults(dataptr dz)
  520. {
  521. int exit_status;
  522. aplptr ap = dz->application;
  523. // set_param_ranges()
  524. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  525. // NB total_input_param_cnt is > 0 !!!
  526. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  527. return(FAILED);
  528. // get_param_ranges()
  529. if(dz->mode == 2) {
  530. ap->lo[REP_ACCEL] = 1.0;
  531. ap->hi[REP_ACCEL] = 10.0;
  532. ap->default_val[REP_ACCEL] = 2.0;
  533. ap->lo[REP_WARP] = 0.1;
  534. ap->hi[REP_WARP] = 10.0;
  535. ap->default_val[REP_WARP] = 0.66;
  536. ap->lo[REP_FADE] = 0.1;
  537. ap->hi[REP_FADE] = 10.0;
  538. ap->default_val[REP_FADE] = .33;
  539. }
  540. ap->lo[REP_RAND] = 1.0;
  541. if(dz->mode == 1)
  542. ap->hi[REP_RAND] = 8.0;
  543. else
  544. ap->hi[REP_RAND] = 2.0;
  545. ap->default_val[REP_RAND] = 1.0;
  546. ap->lo[REP_TRNSP] = 0.0;
  547. ap->hi[REP_TRNSP] = 12.0;
  548. ap->default_val[REP_TRNSP] = 0.0;
  549. ap->lo[REP_SEED] = 0;
  550. ap->hi[REP_SEED] = 256;
  551. ap->default_val[REP_SEED] = 0;
  552. dz->maxmode = 3;
  553. if(!sloom)
  554. put_default_vals_in_all_params(dz);
  555. return(FINISHED);
  556. }
  557. /********************************* PARSE_SLOOM_DATA *********************************/
  558. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  559. {
  560. int exit_status;
  561. int cnt = 1, infilecnt;
  562. int filesize, insams, inbrksize;
  563. double dummy;
  564. int true_cnt = 0;
  565. aplptr ap;
  566. while(cnt<=PRE_CMDLINE_DATACNT) {
  567. if(cnt > argc) {
  568. sprintf(errstr,"Insufficient data sent from TK\n");
  569. return(DATA_ERROR);
  570. }
  571. switch(cnt) {
  572. case(1):
  573. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  574. sprintf(errstr,"Cannot read process no. sent from TK\n");
  575. return(DATA_ERROR);
  576. }
  577. break;
  578. case(2):
  579. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  580. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  581. return(DATA_ERROR);
  582. }
  583. if(dz->mode > 0)
  584. dz->mode--;
  585. //setup_particular_application() =
  586. if((exit_status = setup_repeater_application(dz))<0)
  587. return(exit_status);
  588. ap = dz->application;
  589. break;
  590. case(3):
  591. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  592. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  593. return(DATA_ERROR);
  594. }
  595. if(infilecnt < 1) {
  596. true_cnt = cnt + 1;
  597. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  598. }
  599. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  600. return(exit_status);
  601. break;
  602. case(INPUT_FILETYPE+4):
  603. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  604. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  605. return(DATA_ERROR);
  606. }
  607. break;
  608. case(INPUT_FILESIZE+4):
  609. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  610. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  611. return(DATA_ERROR);
  612. }
  613. dz->insams[0] = filesize;
  614. break;
  615. case(INPUT_INSAMS+4):
  616. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  617. sprintf(errstr,"Cannot read insams sent from TK\n");
  618. return(DATA_ERROR);
  619. }
  620. dz->insams[0] = insams;
  621. break;
  622. case(INPUT_SRATE+4):
  623. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  624. sprintf(errstr,"Cannot read srate sent from TK\n");
  625. return(DATA_ERROR);
  626. }
  627. break;
  628. case(INPUT_CHANNELS+4):
  629. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  630. sprintf(errstr,"Cannot read channels sent from TK\n");
  631. return(DATA_ERROR);
  632. }
  633. break;
  634. case(INPUT_STYPE+4):
  635. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  636. sprintf(errstr,"Cannot read stype sent from TK\n");
  637. return(DATA_ERROR);
  638. }
  639. break;
  640. case(INPUT_ORIGSTYPE+4):
  641. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  642. sprintf(errstr,"Cannot read origstype sent from TK\n");
  643. return(DATA_ERROR);
  644. }
  645. break;
  646. case(INPUT_ORIGRATE+4):
  647. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  648. sprintf(errstr,"Cannot read origrate sent from TK\n");
  649. return(DATA_ERROR);
  650. }
  651. break;
  652. case(INPUT_MLEN+4):
  653. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  654. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  655. return(DATA_ERROR);
  656. }
  657. break;
  658. case(INPUT_DFAC+4):
  659. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  660. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  661. return(DATA_ERROR);
  662. }
  663. break;
  664. case(INPUT_ORIGCHANS+4):
  665. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  666. sprintf(errstr,"Cannot read origchans sent from TK\n");
  667. return(DATA_ERROR);
  668. }
  669. break;
  670. case(INPUT_SPECENVCNT+4):
  671. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  672. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  673. return(DATA_ERROR);
  674. }
  675. dz->specenvcnt = dz->infile->specenvcnt;
  676. break;
  677. case(INPUT_WANTED+4):
  678. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  679. sprintf(errstr,"Cannot read wanted sent from TK\n");
  680. return(DATA_ERROR);
  681. }
  682. break;
  683. case(INPUT_WLENGTH+4):
  684. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  685. sprintf(errstr,"Cannot read wlength sent from TK\n");
  686. return(DATA_ERROR);
  687. }
  688. break;
  689. case(INPUT_OUT_CHANS+4):
  690. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  691. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  692. return(DATA_ERROR);
  693. }
  694. break;
  695. /* RWD these chanegs to samps - tk will have to deal with that! */
  696. case(INPUT_DESCRIPTOR_BYTES+4):
  697. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  698. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  699. return(DATA_ERROR);
  700. }
  701. break;
  702. case(INPUT_IS_TRANSPOS+4):
  703. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  704. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  705. return(DATA_ERROR);
  706. }
  707. break;
  708. case(INPUT_COULD_BE_TRANSPOS+4):
  709. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  710. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  711. return(DATA_ERROR);
  712. }
  713. break;
  714. case(INPUT_COULD_BE_PITCH+4):
  715. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  716. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  717. return(DATA_ERROR);
  718. }
  719. break;
  720. case(INPUT_DIFFERENT_SRATES+4):
  721. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  722. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  723. return(DATA_ERROR);
  724. }
  725. break;
  726. case(INPUT_DUPLICATE_SNDS+4):
  727. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  728. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  729. return(DATA_ERROR);
  730. }
  731. break;
  732. case(INPUT_BRKSIZE+4):
  733. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  734. sprintf(errstr,"Cannot read brksize sent from TK\n");
  735. return(DATA_ERROR);
  736. }
  737. if(inbrksize > 0) {
  738. switch(dz->input_data_type) {
  739. case(WORDLIST_ONLY):
  740. break;
  741. case(PITCH_AND_PITCH):
  742. case(PITCH_AND_TRANSPOS):
  743. case(TRANSPOS_AND_TRANSPOS):
  744. dz->tempsize = inbrksize;
  745. break;
  746. case(BRKFILES_ONLY):
  747. case(UNRANGED_BRKFILE_ONLY):
  748. case(DB_BRKFILES_ONLY):
  749. case(ALL_FILES):
  750. case(ANY_NUMBER_OF_ANY_FILES):
  751. if(dz->extrabrkno < 0) {
  752. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  753. return(DATA_ERROR);
  754. }
  755. if(dz->brksize == NULL) {
  756. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  757. return(PROGRAM_ERROR);
  758. }
  759. dz->brksize[dz->extrabrkno] = inbrksize;
  760. break;
  761. default:
  762. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  763. dz->input_data_type);
  764. return(PROGRAM_ERROR);
  765. }
  766. break;
  767. }
  768. break;
  769. case(INPUT_NUMSIZE+4):
  770. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  771. sprintf(errstr,"Cannot read numsize sent from TK\n");
  772. return(DATA_ERROR);
  773. }
  774. break;
  775. case(INPUT_LINECNT+4):
  776. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  777. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  778. return(DATA_ERROR);
  779. }
  780. break;
  781. case(INPUT_ALL_WORDS+4):
  782. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  783. sprintf(errstr,"Cannot read all_words sent from TK\n");
  784. return(DATA_ERROR);
  785. }
  786. break;
  787. case(INPUT_ARATE+4):
  788. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  789. sprintf(errstr,"Cannot read arate sent from TK\n");
  790. return(DATA_ERROR);
  791. }
  792. break;
  793. case(INPUT_FRAMETIME+4):
  794. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  795. sprintf(errstr,"Cannot read frametime sent from TK\n");
  796. return(DATA_ERROR);
  797. }
  798. dz->frametime = (float)dummy;
  799. break;
  800. case(INPUT_WINDOW_SIZE+4):
  801. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  802. sprintf(errstr,"Cannot read window_size sent from TK\n");
  803. return(DATA_ERROR);
  804. }
  805. break;
  806. case(INPUT_NYQUIST+4):
  807. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  808. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  809. return(DATA_ERROR);
  810. }
  811. break;
  812. case(INPUT_DURATION+4):
  813. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  814. sprintf(errstr,"Cannot read duration sent from TK\n");
  815. return(DATA_ERROR);
  816. }
  817. break;
  818. case(INPUT_MINBRK+4):
  819. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  820. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  821. return(DATA_ERROR);
  822. }
  823. break;
  824. case(INPUT_MAXBRK+4):
  825. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  826. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  827. return(DATA_ERROR);
  828. }
  829. break;
  830. case(INPUT_MINNUM+4):
  831. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  832. sprintf(errstr,"Cannot read minnum sent from TK\n");
  833. return(DATA_ERROR);
  834. }
  835. break;
  836. case(INPUT_MAXNUM+4):
  837. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  838. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  839. return(DATA_ERROR);
  840. }
  841. break;
  842. default:
  843. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  844. return(PROGRAM_ERROR);
  845. }
  846. cnt++;
  847. }
  848. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  849. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  850. return(DATA_ERROR);
  851. }
  852. if(true_cnt)
  853. cnt = true_cnt;
  854. *cmdlinecnt = 0;
  855. while(cnt < argc) {
  856. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  857. return(exit_status);
  858. cnt++;
  859. }
  860. return(FINISHED);
  861. }
  862. /********************************* GET_TK_CMDLINE_WORD *********************************/
  863. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  864. {
  865. if(*cmdlinecnt==0) {
  866. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  867. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  868. return(MEMORY_ERROR);
  869. }
  870. } else {
  871. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  872. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  873. return(MEMORY_ERROR);
  874. }
  875. }
  876. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  877. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  878. return(MEMORY_ERROR);
  879. }
  880. strcpy((*cmdline)[*cmdlinecnt],q);
  881. (*cmdlinecnt)++;
  882. return(FINISHED);
  883. }
  884. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  885. int assign_file_data_storage(int infilecnt,dataptr dz)
  886. {
  887. int exit_status;
  888. int no_sndfile_system_files = FALSE;
  889. dz->infilecnt = infilecnt;
  890. if((exit_status = allocate_filespace(dz))<0)
  891. return(exit_status);
  892. if(no_sndfile_system_files)
  893. dz->infilecnt = 0;
  894. return(FINISHED);
  895. }
  896. /************************* redundant functions: to ensure libs compile OK *******************/
  897. int assign_process_logic(dataptr dz)
  898. {
  899. return(FINISHED);
  900. }
  901. void set_legal_infile_structure(dataptr dz)
  902. {}
  903. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  904. {
  905. return(FINISHED);
  906. }
  907. int setup_internal_arrays_and_array_pointers(dataptr dz)
  908. {
  909. return(FINISHED);
  910. }
  911. int establish_bufptrs_and_extra_buffers(dataptr dz)
  912. {
  913. return(FINISHED);
  914. }
  915. int read_special_data(char *str,dataptr dz)
  916. {
  917. return(FINISHED);
  918. }
  919. int inner_loop
  920. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  921. {
  922. return(FINISHED);
  923. }
  924. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  925. {
  926. return(FINISHED);
  927. }
  928. /******************************** USAGE1 ********************************/
  929. int usage1(void)
  930. {
  931. usage2("repeater");
  932. return(USAGE_ONLY);
  933. }
  934. /********************************************************************************************/
  935. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  936. {
  937. if(!strcmp(prog_identifier_from_cmdline,"repeater")) dz->process = REPEATER;
  938. else {
  939. sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  940. return(USAGE_ONLY);
  941. }
  942. return(FINISHED);
  943. }
  944. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  945. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  946. {
  947. int n;
  948. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  949. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  950. return(MEMORY_ERROR);
  951. }
  952. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  953. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  954. return(MEMORY_ERROR);
  955. }
  956. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  957. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  958. return(MEMORY_ERROR);
  959. }
  960. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  961. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  962. return(MEMORY_ERROR);
  963. }
  964. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  965. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  966. return(MEMORY_ERROR);
  967. }
  968. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  969. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  970. return(MEMORY_ERROR);
  971. }
  972. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  973. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  974. return(MEMORY_ERROR);
  975. }
  976. for(n=0;n<brkcnt;n++) {
  977. dz->brk[n] = NULL;
  978. dz->brkptr[n] = NULL;
  979. dz->brkinit[n] = 0;
  980. dz->brksize[n] = 0;
  981. }
  982. return(FINISHED);
  983. }
  984. /******************************** USAGE2 ********************************/
  985. int usage2(char *str)
  986. {
  987. if(!strcmp(str,"repeater")) {
  988. fprintf(stderr,
  989. "USAGE: repeater repeater\n"
  990. "1-2 infile outfile datafile [-rrand] [-prand] [-sseed]\n"
  991. "3 infile outfile datafile accel warp fade [-rrand] [-prand] [-sseed]\n"
  992. "\n"
  993. "Play source, with specified elements repeating.\n"
  994. "MODE 3 produces dimming, accelerating output, like bouncing object.\n"
  995. "\n"
  996. "MODES 1 & 3 DATAFILE has sets of 4-values, being....\n"
  997. " \"Start-time\" \"End-time\" \"Repeat-cnt\" \"Delay\"\n"
  998. " with one set-of-values for each element to be repeated.\n"
  999. " Elements can overlap, or baktrak in src, & must be at >= %.3lf secs.\n"
  1000. " \"Delay\", is time between start of 1 repeated element & start of next.\n"
  1001. " Delay zero will produce a delay equal to the segment length.\n"
  1002. " Otherwise, delays < 0.05 secs may produce output like oscillator.\n"
  1003. "\n"
  1004. "MODE 2 DATAFILE has sets of 4-values, being....\n"
  1005. " \"Start-time\" \"End-time\" \"Repeat-cnt\" \"Offset\"\n"
  1006. " Similar to MODE 1 but using \"Offset\" instead of \"Delay\".\n"
  1007. " \"Offset\", for any repeating segment,\n"
  1008. " is the gap between end of one repeated element and start of next.\n"
  1009. "\n"
  1010. "RAND Randomise delay:\n"
  1011. " Mode 1&3: Extend each delay-time by a random multiple.\n"
  1012. " Multiplier generated in range you specify (between 1 & 2).\n"
  1013. " Mode 2: Extend each offset-time by a random multiple.\n"
  1014. " Multiplier generated in range you specify (between 1 & 8).\n"
  1015. " Value 1 gives NO randomisation. \"RAND\" may vary through time.\n"
  1016. "\n"
  1017. "PRAND Randomise pitch of repeats within given semitone range (between 0 & 12)\n"
  1018. " \"PRAND\" may vary through time.\n"
  1019. "\n"
  1020. "SEED An integer value. repeated runs of process with same input\n"
  1021. " and same seed value will give identical output.\n"
  1022. "\n"
  1023. "ACCEL Delay (& segment) shortening by end of repeats\n"
  1024. " e.g. accel = 2 gradually shortens delay to 1/2 its duration.\n"
  1025. "WARP Warps delay change. 1 no warp. > 1 shortens less initially, more later.\n"
  1026. "FADE Decay curve. 1 linear, >1 fast then slow decay, <1 slow then fast.\n" ,(int)round(REPSPLEN * 2) * MS_TO_SECS);
  1027. } else
  1028. fprintf(stderr,"Unknown option '%s'\n",str);
  1029. return(USAGE_ONLY);
  1030. }
  1031. int usage3(char *str1,char *str2)
  1032. {
  1033. fprintf(stderr,"Insufficient parameters on command line.\n");
  1034. return(USAGE_ONLY);
  1035. }
  1036. /******************************** REPEATER ********************************/
  1037. int repeater(dataptr dz)
  1038. {
  1039. int exit_status, chans = dz->infile->channels, ch, at_start, overlap, varypitch;
  1040. float *ibuf = dz->sampbuf[0], *iovflwbuf = dz->sampbuf[1], *obuf = dz->sampbuf[2], *repbuf = dz->sampbuf[4], *reprepbuf = dz->sampbuf[5], *segbuf;
  1041. double splicelen = REPSPLEN * MS_TO_SECS, srate = (double)dz->infile->srate, maxtransdown = 1.0, maxexpand = 1.0;
  1042. int gp_splicesamps = (int)round(splicelen * srate), possible_gp_samps_to_read, maxrepbufpos, samps_written, outsamps = 0, lastrepbufpos;
  1043. double dgp_splicesamps = (double)gp_splicesamps, val, rnd, thistime, incr, md, frac, diff;
  1044. int total_splicesamps = gp_splicesamps * chans, last_gp_absendsamp, ibufpos, obufpos, repbufpos, bufpos_in_iovflw, totalreps, rep, n, m, k, baktrak;
  1045. int samps_to_read, delaysamps, gp_abssttsamp, gp_absendsamp, repeats, gp_delaysamps, gp_samps_to_read, samps_to_write, startdelay = 0, datacnt, thisdata;
  1046. double *segdata = dz->parray[0];
  1047. int isshorten;
  1048. double lenchange, lenchangeincr = 0.0, lenfact, thisfade, endspliceval;
  1049. int inital_gp_delaysamps = 0, initial_gp_samps_to_read = 0, gp_endsplice = 0, gp_endsplice_stt = 0, endsplice = 0, endsplice_stt = 0;
  1050. srand((int)dz->iparam[REP_SEED]);
  1051. if(sloom) {
  1052. if((exit_status = calc_output_dur(&outsamps,dz))<0)
  1053. return exit_status;
  1054. dz->tempsize = outsamps;
  1055. }
  1056. if(dz->mode != 1) { // Setup enveloping arrays, for signal normalisation
  1057. dz->envwindowlen = gp_splicesamps * 2; // half-windowlen must be no larger than splicesamps (ensuring envelope is val 1 throughout splice)
  1058. dz->envwindowlen *= chans;
  1059. dz->arraysize = dz->buflen2/dz->envwindowlen;
  1060. dz->arraysize += SAFETY;
  1061. if((dz->parray[1] = (double *)malloc(dz->arraysize * sizeof(double)))==NULL) {
  1062. sprintf(errstr,"INSUFFICIENT MEMORY to create envelope array.\n");
  1063. return(MEMORY_ERROR);
  1064. }
  1065. if((dz->iparray = (int **)malloc(sizeof(int *)))==NULL) {
  1066. sprintf(errstr,"INSUFFICIENT MEMORY to create envelope max locations array (1).\n");
  1067. return(MEMORY_ERROR);
  1068. }
  1069. if((dz->iparray[0] = (int *)malloc(dz->arraysize * sizeof(int)))==NULL) {
  1070. sprintf(errstr,"INSUFFICIENT MEMORY to create envelope max locations array (2).\n");
  1071. return(MEMORY_ERROR);
  1072. }
  1073. }
  1074. at_start = 1;
  1075. last_gp_absendsamp = 0;
  1076. if((exit_status = read_samps(iovflwbuf,dz))<0) // Initially read into input-overflow-buf
  1077. return exit_status;
  1078. ibufpos = dz->buflen; // and point into it
  1079. obufpos = 0;
  1080. totalreps = dz->itemcnt/4; // For every repeat unit in data
  1081. for(rep=0, datacnt = 0; rep< totalreps;rep++,datacnt+=4) {
  1082. thisdata = datacnt; // Get the repeat-params
  1083. thistime = segdata[thisdata];
  1084. gp_abssttsamp = (int)round(segdata[thisdata++] * srate);
  1085. gp_absendsamp = (int)round(segdata[thisdata++] * srate);
  1086. repeats = (int)round(segdata[thisdata++]);
  1087. gp_delaysamps = (int)round(segdata[thisdata] * srate);
  1088. if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
  1089. return exit_status;
  1090. varypitch = 0;
  1091. if(dz->param[REP_TRNSP] != 0.0) {
  1092. varypitch = 1;
  1093. maxtransdown = pow(2.0,-dz->param[REP_TRNSP]/SEMITONES_PER_OCTAVE);
  1094. maxexpand = 1.0/maxtransdown;
  1095. }
  1096. gp_samps_to_read = gp_abssttsamp - last_gp_absendsamp;
  1097. if(gp_samps_to_read > 0) { // If next segment is beyond end of last segment, read from infile.
  1098. // READ any of infile BETWEEN SEGS
  1099. while(obufpos >= dz->buflen + total_splicesamps) {
  1100. if((exit_status = write_and_reset_obuf(dz->buflen,&obufpos,dz))<0)
  1101. return(exit_status); // check if obuf has overflowed
  1102. }
  1103. gp_samps_to_read += gp_splicesamps; // Allow for endsplice-down in read-segment by reading extra from input
  1104. for(n=0,m = gp_samps_to_read - 1;n < gp_samps_to_read; n++,m--) {
  1105. if(n < gp_splicesamps) {
  1106. if(at_start)
  1107. val = 1.0;
  1108. else
  1109. val = (double)n/dgp_splicesamps;// Copy to output, with splices at start, if not at start of infile
  1110. } else if (m < gp_splicesamps)
  1111. val = (double)m/dgp_splicesamps; // and splice at end
  1112. else
  1113. val = 1.0;
  1114. for(ch = 0;ch < chans; ch++) {
  1115. obuf[obufpos] = (float)(obuf[obufpos] + (ibuf[ibufpos] * val));
  1116. obufpos++;
  1117. ibufpos++;
  1118. }
  1119. if(obufpos >= dz->buflen + total_splicesamps) {
  1120. if((exit_status = write_and_reset_obuf(dz->buflen,&obufpos,dz))<0)
  1121. return(exit_status);
  1122. }
  1123. if(ibufpos >= dz->buflen * 2) {
  1124. if((exit_status = reset_ibuf_and_read(&ibufpos,dz))<0)
  1125. return(exit_status);
  1126. if(dz->ssampsread == 0) {
  1127. sprintf(errstr,"Reached end of input prematurely\n");
  1128. return PROGRAM_ERROR;
  1129. }
  1130. }
  1131. }
  1132. at_start = 0;
  1133. obufpos -= total_splicesamps; // Baktrack by splicelen in output;
  1134. ibufpos -= total_splicesamps; // Baktrack by splicelen in input, for start-read of segment.
  1135. } else {
  1136. // ELSE go directly to the new segment
  1137. baktrak = (last_gp_absendsamp - gp_abssttsamp) * chans;
  1138. if(baktrak > 0) { // If this seg starts BEFORE END but AFTER START of previous seg, baktrak in current buf.
  1139. ibufpos -= baktrak; // ibuf has a prebuf as big as the largest possible segment, so baktracking will fall inside inbuf.
  1140. if(ibufpos < 0) { // However, if this segment starts BEFORE START of previous segment, baktraking may go beyond start of prebuf,
  1141. sndseekEx(dz->ifd[0],0,0); // in which case return to start of file ...
  1142. dz->total_samps_read = 0;
  1143. dz->ssampsread = 0; // ...and read...
  1144. memset((char *)ibuf,0,2 * dz->buflen * sizeof(float));
  1145. if((exit_status = read_samps(iovflwbuf,dz))<0)
  1146. return exit_status;
  1147. ibufpos = dz->buflen; // ...until we find required sample-position
  1148. while(dz->total_samps_read < gp_abssttsamp * chans) {
  1149. if((exit_status = reset_ibuf_and_read(&ibufpos,dz))<0)
  1150. return(exit_status);
  1151. if(dz->ssampsread == 0) {
  1152. sprintf(errstr,"Reached end of input prematurely during baktrak in infile.\n");
  1153. return PROGRAM_ERROR;
  1154. }
  1155. }
  1156. if(dz->total_samps_read == dz->ssampsread)
  1157. at_start = 1;
  1158. }
  1159. }
  1160. }
  1161. // READ SEGMENT
  1162. gp_samps_to_read = gp_absendsamp - gp_abssttsamp;// Read the rep-segment into rep-buffer
  1163. if(dz->mode != 1) {
  1164. if(gp_delaysamps == 0)
  1165. gp_delaysamps = gp_samps_to_read; // Special delay value, zero, delays sample by its complete length
  1166. }
  1167. gp_samps_to_read += gp_splicesamps;
  1168. if(varypitch && (maxexpand > 1.0)) // IF segments are transposed downwards, check if they will overlap
  1169. possible_gp_samps_to_read = (int)ceil((double)gp_samps_to_read * maxexpand);
  1170. else
  1171. possible_gp_samps_to_read = gp_samps_to_read;
  1172. if(dz->mode != 1 && (gp_delaysamps < possible_gp_samps_to_read)) {
  1173. overlap = 1; // Delays WILL (POSSIBLY) OVERLAP: write ALL into reprepbuf
  1174. segbuf = reprepbuf;
  1175. memset((char *)segbuf,0,dz->buflen2 * sizeof(float));
  1176. } else { // Delays do not overlap, write 1 segment in repbuf
  1177. segbuf = repbuf;
  1178. overlap = 0;
  1179. } // Zero the segment buffer
  1180. memset((char *)repbuf,0,dz->buflen2 * sizeof(float));
  1181. repbufpos = 0; // Write one repeat segment (at original pitch) to appropriate buffer
  1182. for(n=0,m = gp_samps_to_read - 1;n < gp_samps_to_read; n++,m--) {
  1183. if(n < gp_splicesamps) {
  1184. if(at_start)
  1185. val = 1.0;
  1186. else
  1187. val = (double)n/dgp_splicesamps; // Copy to relevant segment-buffer, with splice at start, if not at start of infile
  1188. } else if (m < gp_splicesamps)
  1189. val = (double)m/dgp_splicesamps; // and splice at end
  1190. else
  1191. val = 1.0;
  1192. for(ch = 0;ch < chans; ch++) {
  1193. segbuf[repbufpos] = (float)(ibuf[ibufpos] * val);
  1194. repbufpos++;
  1195. ibufpos++;
  1196. }
  1197. if(repbufpos >= dz->buflen2) {
  1198. sprintf(errstr,"Input segment has overflowed segment buffer.\n");
  1199. return PROGRAM_ERROR;
  1200. }
  1201. if(ibufpos >= 2 * dz->buflen) {
  1202. if((exit_status = reset_ibuf_and_read(&ibufpos,dz))<0)
  1203. return(exit_status);
  1204. }
  1205. }
  1206. at_start = 0;
  1207. samps_to_read = gp_samps_to_read * chans;
  1208. delaysamps = gp_delaysamps * chans;
  1209. isshorten = 0;
  1210. thisfade = 1.0;
  1211. endspliceval = 1.0;
  1212. if(overlap) { // Delays OVERLAP: write ALL into repbuf, from single copy in reprepbuf
  1213. if(dz->mode == 2) {
  1214. if(dz->param[REP_ACCEL] != 1.0) {
  1215. lenchange = 1.0 - (1.0/dz->param[REP_ACCEL]);
  1216. lenchangeincr = lenchange/(double)(repeats - 1);
  1217. isshorten = 1;
  1218. }
  1219. inital_gp_delaysamps = gp_delaysamps;
  1220. initial_gp_samps_to_read = gp_samps_to_read;
  1221. }
  1222. maxrepbufpos = 0;
  1223. lastrepbufpos = 0;
  1224. for(n=0;n<repeats;n++) { // Copy repeating segments into segment-buffer
  1225. if(dz->mode == 2) {
  1226. if(isshorten) {
  1227. lenfact = 1.0 - pow(lenchangeincr * (double)n,dz->param[REP_WARP]);
  1228. gp_delaysamps = (int)round(inital_gp_delaysamps * lenfact);
  1229. delaysamps = gp_delaysamps * chans;
  1230. gp_samps_to_read = (int)round(initial_gp_samps_to_read * lenfact);
  1231. gp_endsplice = min(gp_samps_to_read,gp_splicesamps);
  1232. gp_endsplice_stt = gp_samps_to_read - gp_endsplice;
  1233. endsplice = gp_endsplice * chans;
  1234. endsplice_stt = gp_endsplice_stt * chans;
  1235. samps_to_read = gp_samps_to_read * chans;
  1236. }
  1237. thisfade = pow((double)(repeats - n)/(double)repeats,dz->param[REP_FADE]) ;
  1238. }
  1239. if(dz->param[REP_RAND] > 1.0) {
  1240. val = dz->param[REP_RAND] - 1.0; // 0 to maxval-1 (1-2 -> 0-1: 1-8 -> 0-7)
  1241. rnd = drand48(); // 0 to 1
  1242. rnd *= val; // 0 to 1*rnd OR 0 to 7*rnd (rnd < 1)
  1243. rnd += 1.0; // 1 to 2*rnd OR 1 to 8*rnd (rnd < 1)
  1244. delaysamps = (int)round(gp_delaysamps * rnd) * chans;
  1245. }
  1246. repbufpos = lastrepbufpos + delaysamps; // Advancing by delay-time
  1247. lastrepbufpos = repbufpos;
  1248. endspliceval = 1.0;
  1249. if(varypitch && (n > 0)) { // If there's pitch-variation
  1250. val = (drand48() * 2.0) - 1.0; // Get random value in range 0 to +- given semitone-range
  1251. val *= dz->param[REP_TRNSP];
  1252. incr = pow(2.0,val/SEMITONES_PER_OCTAVE); // Convert to an increment for table read
  1253. md = 0;
  1254. while(md < gp_samps_to_read) { // Transpose repeated segment before copying segment buffer
  1255. m = (int)floor(md);
  1256. frac = md - (double)m;
  1257. if(isshorten && (md > gp_endsplice_stt))
  1258. endspliceval = 1.0 - ((md - (double)gp_endsplice_stt)/(double)gp_endsplice);
  1259. for(ch=0,k=m*chans;ch<chans;ch++,k++) {
  1260. val = segbuf[k];
  1261. diff = segbuf[k+chans] - val;
  1262. val += diff*frac;
  1263. if(dz->mode == 2)
  1264. val *= thisfade*endspliceval;
  1265. repbuf[repbufpos] = (float)(repbuf[repbufpos] + val);
  1266. if(++repbufpos >= dz->buflen2) {
  1267. sprintf(errstr,"segment buffer too short to contain repeated overlapping segments (1).\n");
  1268. return PROGRAM_ERROR;
  1269. }
  1270. }
  1271. md += incr;
  1272. }
  1273. maxrepbufpos = max(maxrepbufpos,repbufpos);
  1274. } else {
  1275. for(m=0; m< samps_to_read;m++) {
  1276. if(isshorten && (m > endsplice_stt))
  1277. endspliceval = 1.0 - ((m - (double)endsplice_stt)/(double)endsplice);
  1278. repbuf[repbufpos] = (float)(repbuf[repbufpos] + (segbuf[m] * thisfade * endspliceval)); // Add repeating units back into segment buffer
  1279. if(++repbufpos >= dz->buflen2) {
  1280. sprintf(errstr,"segment buffer too short to contain repeated overlapping segments (1).\n");
  1281. return PROGRAM_ERROR;
  1282. }
  1283. }
  1284. maxrepbufpos = max(maxrepbufpos,repbufpos);
  1285. }
  1286. }
  1287. samps_to_write = maxrepbufpos;
  1288. if((exit_status = normalise_buffer(samps_to_write,dz))<0) // Normalise the output in such a way
  1289. return(exit_status); // that start and end normalisations are 1.0
  1290. for(n = 0; n < samps_to_write; n++) {
  1291. obuf[obufpos] = (float)(obuf[obufpos] + repbuf[n]); // Add whole set of repeating units to output
  1292. if(++obufpos >= dz->buflen + total_splicesamps) {
  1293. if((exit_status = write_and_reset_obuf(dz->buflen,&obufpos,dz))<0)
  1294. return(exit_status);
  1295. }
  1296. }
  1297. } else { // Delays will NOT overlap
  1298. if(dz->mode == 2) {
  1299. if(dz->param[REP_ACCEL] != 1.0) {
  1300. lenchange = 1.0 - (1.0/dz->param[REP_ACCEL]);
  1301. lenchangeincr = lenchange/(double)(repeats - 1);
  1302. isshorten = 1;
  1303. }
  1304. inital_gp_delaysamps = gp_delaysamps;
  1305. initial_gp_samps_to_read = gp_samps_to_read;
  1306. }
  1307. if(dz->mode == 1) // In mode 1
  1308. startdelay = 0; // Delaytime starts at END of segment
  1309. for(n=0;n<repeats;n++) {
  1310. if(dz->mode == 2) {
  1311. if(isshorten) {
  1312. lenfact = 1.0 - pow(lenchangeincr * (double)n,dz->param[REP_WARP]);
  1313. gp_delaysamps = (int)round(inital_gp_delaysamps * lenfact);
  1314. gp_samps_to_read = (int)round(initial_gp_samps_to_read * lenfact);
  1315. gp_endsplice = min(gp_samps_to_read,gp_splicesamps);
  1316. gp_endsplice_stt = gp_samps_to_read - gp_endsplice;
  1317. endsplice = gp_endsplice * chans;
  1318. endsplice_stt = gp_endsplice_stt * chans;
  1319. samps_to_read = gp_samps_to_read * chans;
  1320. }
  1321. thisfade = pow((double)(repeats - n)/(double)repeats,dz->param[REP_FADE]) ;
  1322. }
  1323. samps_written = 0;
  1324. repbufpos = 0;
  1325. endspliceval = 1.0;
  1326. if(varypitch && (n > 0)) { // If there's pitch-variation
  1327. val = (drand48() * 2.0) - 1.0;
  1328. val *= dz->param[REP_TRNSP];
  1329. incr = pow(2.0,val/SEMITONES_PER_OCTAVE);
  1330. md = 0;
  1331. while(md < gp_samps_to_read) { // Transpose repeated segment before copying to output buffer
  1332. m = (int)floor(md);
  1333. frac = md - (double)m;
  1334. if(isshorten && (md > gp_endsplice_stt))
  1335. endspliceval = 1.0 - ((md - (double)gp_endsplice_stt)/(double)gp_endsplice);
  1336. for(ch=0,k=m*chans;ch<chans;ch++,k++) {
  1337. val = segbuf[k];
  1338. diff = segbuf[k+chans] - val;
  1339. val += diff*frac;
  1340. if(dz->mode == 2)
  1341. val *= thisfade*endspliceval;
  1342. obuf[obufpos] = (float)(obuf[obufpos] + val);
  1343. if(++obufpos >= dz->buflen + total_splicesamps) { // (startsplice overlaps with existing obuf data, so use "add")
  1344. if((exit_status = write_and_reset_obuf(dz->buflen,&obufpos,dz))<0)
  1345. return(exit_status);
  1346. }
  1347. samps_written++;
  1348. }
  1349. md += incr;
  1350. }
  1351. } else {
  1352. while(repbufpos < samps_to_read) {
  1353. if(isshorten && (repbufpos > endsplice_stt))
  1354. endspliceval = 1.0 - ((repbufpos - (double)endsplice_stt)/(double)endsplice);
  1355. if(dz->mode == 2)
  1356. repbuf[repbufpos] = (float)(repbuf[repbufpos] * thisfade * endspliceval); // Do any fades or endsplicing
  1357. obuf[obufpos] = (float)(obuf[obufpos] + repbuf[repbufpos++]);// Add repeating unit to output
  1358. if(++obufpos >= dz->buflen + total_splicesamps) { // (startsplice overlaps with existing obuf data, so use "add")
  1359. if((exit_status = write_and_reset_obuf(dz->buflen,&obufpos,dz))<0)
  1360. return(exit_status);
  1361. }
  1362. samps_written++;
  1363. }
  1364. }
  1365. if(dz->param[REP_RAND] > 1.0) {
  1366. val = dz->param[REP_RAND] - 1.0;
  1367. rnd = drand48();
  1368. rnd *= val;
  1369. rnd += 1.0;
  1370. delaysamps = (int)round(gp_delaysamps * rnd) * chans;
  1371. } else
  1372. delaysamps = gp_delaysamps * chans;
  1373. if(dz->mode != 1) // In modes 0 & 2
  1374. startdelay = samps_written; // Delaytime starts at START of segment
  1375. for(m=startdelay;m < delaysamps; m++) {
  1376. if(++obufpos >= dz->buflen + total_splicesamps) {
  1377. if((exit_status = write_and_reset_obuf(dz->buflen,&obufpos,dz))<0)
  1378. return(exit_status);
  1379. }
  1380. }
  1381. }
  1382. }
  1383. obufpos -= total_splicesamps; // Baktrack by splicelen in output;
  1384. ibufpos -= total_splicesamps; // Restore ibufpos to true end-of-segment time, ready for next read.
  1385. last_gp_absendsamp = gp_absendsamp; // Set sample position of end of segment read
  1386. }
  1387. bufpos_in_iovflw = ibufpos - dz->buflen; // ibufpos is normally in iovflwbuf (>= dz->buflen) unless it's baktracked
  1388. if(bufpos_in_iovflw < dz->ssampsread) { // If there are still input samples remaining to be read (these are always in iovflw)
  1389. n = 0;
  1390. while(bufpos_in_iovflw < dz->ssampsread) {
  1391. if(n < gp_splicesamps)
  1392. val = (double)n/dgp_splicesamps; // Copy to repeat-buffer, with splices at start
  1393. else
  1394. val = 1.0;
  1395. for(ch = 0;ch < chans; ch++) {
  1396. obuf[obufpos] = (float)(obuf[obufpos] + (ibuf[ibufpos] * val));
  1397. obufpos++;
  1398. ibufpos++;
  1399. bufpos_in_iovflw++;
  1400. }
  1401. if(obufpos >= dz->buflen + total_splicesamps) {
  1402. if((exit_status = write_and_reset_obuf(dz->buflen,&obufpos,dz))<0)
  1403. return(exit_status);
  1404. }
  1405. if(ibufpos >= 2 * dz->buflen) {
  1406. if((exit_status = reset_ibuf_and_read(&ibufpos,dz))<0)
  1407. return(exit_status);
  1408. bufpos_in_iovflw = 0;
  1409. }
  1410. n++;
  1411. }
  1412. } else
  1413. obufpos += total_splicesamps; // Restore obufpos to its true position
  1414. dz->process = GREV;
  1415. if((exit_status = write_samps(obuf,obufpos,dz))<0)
  1416. return(exit_status);
  1417. dz->process = REPEATER;
  1418. return FINISHED;
  1419. }
  1420. /**************************** HANDLE_THE_SPECIAL_DATA ****************************/
  1421. int handle_the_special_data(char *str,double *maxseglen,double *maxovlp,dataptr dz)
  1422. {
  1423. int n, k, cnt, curtail, idummy, linecnt, warned = 0, chans = dz->infile->channels;
  1424. FILE *fp;
  1425. char temp[200], *p;
  1426. double dummy = 0, lasttime, lastendtime = 0.0, seglen, srate = (double)dz->infile->srate;
  1427. double splicelen, twosplicelen, lastdur = 0.0;
  1428. double max_ovlpbuf; // Finds size of buffer needed for any overlapping sets of delayed segments
  1429. int splicesamps, repeats = 0;
  1430. *maxovlp = 0.0;
  1431. splicelen = REPSPLEN * MS_TO_SECS; // Find minimum permissible size of segments == >two-splicelengths
  1432. splicesamps = (int)ceil(splicelen * srate);
  1433. splicelen = (double)(splicesamps + chans)/srate; // Add a sample (for each chan) for splicelen, for safety
  1434. twosplicelen = (double)((splicesamps + chans) * 2)/srate;
  1435. if((fp = fopen(str,"r"))==NULL) {
  1436. sprintf(errstr,"Cannot open file \"%s\" to read repeater data.\n",str);
  1437. return(DATA_ERROR);
  1438. }
  1439. cnt = 0;
  1440. lasttime = 0.0;
  1441. curtail = 0;
  1442. linecnt = 0;
  1443. while(fgets(temp,200,fp)!=NULL) {
  1444. p = temp;
  1445. while(isspace(*p))
  1446. p++;
  1447. if(*p == ';' || *p == ENDOFSTR) // Allow comments in file
  1448. continue;
  1449. cnt = 0;
  1450. while(get_float_from_within_string(&p,&dummy)) {
  1451. if(curtail == 1)
  1452. break; // if in midst of current seg (cnt > 0), but fell off end of data, break now before linecnt is incremented
  1453. k = cnt % 4;
  1454. if(k == 0 && curtail == 2) // if at start of a new seg (cnt == 0), but we reached end of file in last segment, break now
  1455. break;
  1456. switch(k) {
  1457. case(0):
  1458. if(dummy < 0.0) {
  1459. sprintf(errstr,"Segment start-time (%lf) less than zero at line %d in file \"%s\".\n",dummy,linecnt+1,str);
  1460. return DATA_ERROR;
  1461. }
  1462. if(dummy >= dz->duration - splicelen) {
  1463. if(linecnt == 0) {
  1464. sprintf(errstr,"1st segment start-time (%lf) close to or > infile-end (%lf) in file \"%s\".\n",dummy,dz->duration,str);
  1465. return DATA_ERROR;
  1466. } else {
  1467. fprintf(stdout,"WARNING: line %d in file \"%s\" : start-time (%lf) close to or > infile-end (%lf).\n",linecnt+1,str,dummy,dz->duration);
  1468. fprintf(stdout,"WARNING: Ignoring repetition-data at and beyond this time in file \"%s\".\n",str);
  1469. fflush(stdout);
  1470. curtail = 1;
  1471. }
  1472. }
  1473. lasttime = dummy;
  1474. break;
  1475. case(1):
  1476. if(dummy - lasttime <= twosplicelen) {
  1477. sprintf(errstr,"Segment on line %d in file \"%s\", dur %lf, too short for splicing (min dur %lf).\n",linecnt+1,str,dummy - lasttime,twosplicelen);
  1478. return DATA_ERROR;
  1479. }
  1480. if(dummy >= dz->duration) {
  1481. if(dz->duration - lasttime <= twosplicelen) {
  1482. fprintf(stdout,"WARNING: Segment on line %d in file \"%s\", ends after infile-end and is hence too short.\n",linecnt+1,str /*,twosplicelen*/); //RWD arg unused...?.
  1483. fprintf(stdout,"WARNING: Ignoring this and later segments.\n");
  1484. fflush(stdout);
  1485. curtail = 1; // cnt is complete after end of previous viable segment
  1486. break;
  1487. } else {
  1488. fprintf(stdout,"WARNING: line %d in file \"%s\" : segment end-time (%lf) beyond infile-end (%lf).\n",linecnt+1,str,dummy,dz->duration);
  1489. fprintf(stdout,"WARNING: Curtailing segment to finish at end of src-file (and ignoring any subsequent segments).\n");
  1490. fflush(stdout);
  1491. curtail = 2; // read rest of this seg, but ignore any further segs
  1492. }
  1493. }
  1494. lastendtime = dummy;
  1495. lastdur = dummy - lasttime;
  1496. break;
  1497. case(2):
  1498. idummy = (int)round(dummy);
  1499. if(dummy != (double)idummy) {
  1500. sprintf(errstr,"Non-integer repeat value on line %d in file \"%s\".\n",linecnt+1,str);
  1501. return DATA_ERROR;
  1502. }
  1503. if(idummy < 2 && idummy != 0) {
  1504. sprintf(errstr,"Repeat value less than 2 on line %d in file \"%s\".\n",linecnt+1,str);
  1505. return DATA_ERROR;
  1506. }
  1507. repeats= idummy;
  1508. break;
  1509. case(3):
  1510. switch(dz->mode) {
  1511. case(0):
  1512. case(2):
  1513. if(dummy < REPMINDEL && dummy != 0.0) {
  1514. if(!warned) {
  1515. fprintf(stdout,"WARNING: (Non-zero) Delay (%.3lf) <= %.3lf on line %d in file \"%s\".\n",dummy,REPMINDEL,linecnt+1,str);
  1516. fprintf(stdout,"WARNING: This may produce unexpected output, like an oscillator.\n");
  1517. fflush(stdout); // ---------------------------
  1518. warned = 1;
  1519. }
  1520. } // | |---------------------------
  1521. if(dummy < lastdur + splicelen) { // If delayed repeats overlap // delay |---------------------------
  1522. max_ovlpbuf = (dummy * repeats) + lastdur + splicelen; // | | | |--------------------------- __
  1523. *maxovlp = max(*maxovlp,max_ovlpbuf); // Remember maxoverlap dur // | | | |
  1524. } // For bufsize calculations. // |delay*rpts | + (last)dur |+splicelen
  1525. break;
  1526. case(1): // Delayed repeats never overlap.
  1527. break;
  1528. }
  1529. break;
  1530. default:
  1531. sprintf(errstr,"Too many values (%d) on line %d in file \"%s\": Need only 4.\n",cnt,linecnt+1,str);
  1532. return DATA_ERROR;
  1533. }
  1534. cnt++;
  1535. }
  1536. if(cnt < 4) {
  1537. sprintf(errstr,"Too few values (%d) on line %d in file \"%s\": Need 4.\n",cnt,linecnt+1,str);
  1538. return DATA_ERROR;
  1539. }
  1540. linecnt++;
  1541. }
  1542. if(linecnt == 0) {
  1543. sprintf(errstr,"No viable repetition data found in file \"%s\".\n",str);
  1544. return(DATA_ERROR);
  1545. }
  1546. dz->itemcnt = linecnt * 4;
  1547. if((dz->parray = (double **)malloc(2 * sizeof(double *)))==NULL) {
  1548. sprintf(errstr,"INSUFFICIENT MEMORY to create Repetition data array.\n");
  1549. return(MEMORY_ERROR);
  1550. }
  1551. if((dz->parray[0] = (double *)malloc(dz->itemcnt * sizeof(double)))==NULL) {
  1552. sprintf(errstr,"INSUFFICIENT MEMORY to create Repetition data array.\n");
  1553. return(MEMORY_ERROR);
  1554. }
  1555. cnt = 0;
  1556. fseek(fp,0,0);
  1557. while(fgets(temp,200,fp)!=NULL) {
  1558. p = temp;
  1559. while(isspace(*p))
  1560. p++;
  1561. if(*p == ';' || *p == ENDOFSTR) // Allow comments in file
  1562. continue;
  1563. while(get_float_from_within_string(&p,&dummy))
  1564. dz->parray[0][cnt++] = dummy;
  1565. if(cnt >= dz->itemcnt)
  1566. break;
  1567. }
  1568. lastendtime = dz->parray[0][dz->itemcnt - 3];
  1569. if(lastendtime > dz->duration)
  1570. dz->parray[0][dz->itemcnt - 3] = dz->duration;
  1571. *maxseglen = 0.0;
  1572. for(n = 0; n < dz->itemcnt;n+=4) {
  1573. seglen = dz->parray[0][n+1] - dz->parray[0][n];
  1574. *maxseglen = max(seglen,*maxseglen);
  1575. }
  1576. return FINISHED;
  1577. }
  1578. /******************************** CREATE_REPEATER_SNDBUFS ********************************/
  1579. int create_repeater_sndbufs(double maxseglen, double maxovlp, dataptr dz)
  1580. {
  1581. int exit_status, chans = dz->infile->channels;
  1582. int bigbufsize, secsize, maxovlpsamps;
  1583. int framesize = F_SECSIZE * chans;
  1584. double maxrand = 0.0, maxtransp = 0.0, maxtranspdn, maxexpand = 1.0, srate = (double)dz->infile->srate;
  1585. int splicespace;
  1586. if(dz->sbufptr == 0 || dz->sampbuf == 0) {
  1587. sprintf(errstr,"buffer pointers not allocated: create_sndbufs()\n");
  1588. return(PROGRAM_ERROR);
  1589. }
  1590. splicespace = (int)ceil(REPSPLEN * MS_TO_SECS * srate) * chans;// Allow for inbuf splice-backtraks and splice-beyond-endtime as segments cut
  1591. // BUFLEN2 to contain segments for repeating
  1592. if(dz->brksize[REP_RAND]) {
  1593. if((exit_status = get_maxvalue_in_brktable(&maxrand,REP_RAND,dz))<0)
  1594. return exit_status;
  1595. } else if(dz->param[REP_RAND] > 1.0) // Start with the max seglen to handle overlapping segments
  1596. maxrand = dz->param[REP_RAND];
  1597. if(maxrand > 1.0) // Allow for maximum possible expansion of "overlapping" segs, by random expansion!!
  1598. maxovlp *= maxrand;
  1599. if(dz->brksize[REP_TRNSP]) {
  1600. if((exit_status = get_maxvalue_in_brktable(&maxtransp,REP_TRNSP,dz))<0)
  1601. return exit_status;
  1602. } else // Find the maximum transposition
  1603. maxtransp = dz->param[REP_TRNSP];
  1604. if(maxtransp > 0.0) { // If segments are transposed, they could be transposed downwards (and therefore be longer)
  1605. maxtranspdn = pow(2.0,-maxtransp/SEMITONES_PER_OCTAVE); // Convert semitones to frq-ratio for fownwarfd transposition.
  1606. maxexpand = 1.0/maxtranspdn; // Transposing down an 8va (frq ratio 1/2) makes sound 2 * longer, so take reciprocal
  1607. maxovlp *= maxexpand; // Increase length of overlap-buffer by this amount as all segs could be expanded and overlap
  1608. maxseglen *= maxexpand; // Increase length of single-segment-buffer by this amount
  1609. }
  1610. maxovlpsamps = (int)ceil(maxovlp * srate) * chans;
  1611. dz->buflen2 = (int)ceil(maxseglen * srate) * chans; // Size = max seglen
  1612. dz->buflen2 = max(dz->buflen2,maxovlpsamps); // Or = max length of any overlapping repeats captured in segment buffer
  1613. dz->buflen2 += splicespace * 2; // Must be large enough to fit and splice area at end of segment
  1614. bigbufsize = (int)Malloc(-1);
  1615. dz->buflen = bigbufsize/sizeof(float); // dz->buflen2 will accomodate largest cut-segment
  1616. dz->buflen = max(dz->buflen,dz->buflen2) + (splicespace * 2); // must be large enough to fit largest cut-segment and splice baktrak
  1617. secsize = dz->buflen/framesize;
  1618. if(secsize * framesize != dz->buflen)
  1619. secsize++;
  1620. dz->buflen = secsize * framesize;
  1621. secsize = dz->buflen2/framesize;
  1622. if(secsize * framesize != dz->buflen2)
  1623. secsize++;
  1624. dz->buflen2 = secsize * framesize;
  1625. if(dz->buflen <= 0) {
  1626. sprintf(errstr,"INSUFFICIENT MEMORY to create input and output sound buffers.\n");
  1627. return(PROGRAM_ERROR);
  1628. }
  1629. if(dz->buflen2 <= 0) {
  1630. sprintf(errstr,"INSUFFICIENT MEMORY to create delay-segments sound buffer.\n");
  1631. return(PROGRAM_ERROR);
  1632. }
  1633. bigbufsize = ((dz->buflen * 4) + (dz->buflen2 * 2)) * sizeof(float);
  1634. if((dz->bigbuf = (float *)malloc(bigbufsize)) == NULL) {
  1635. sprintf(errstr,"INSUFFICIENT MEMORY to create total sound buffers.\n");
  1636. return(PROGRAM_ERROR);
  1637. }
  1638. dz->sbufptr[0] = dz->sampbuf[0] = dz->bigbuf; // Inbuf
  1639. dz->sbufptr[1] = dz->sampbuf[1] = dz->sampbuf[0] + dz->buflen; // Inbuf overflow
  1640. dz->sbufptr[2] = dz->sampbuf[2] = dz->sampbuf[1] + dz->buflen; // Outbuf
  1641. dz->sbufptr[3] = dz->sampbuf[3] = dz->sampbuf[2] + dz->buflen; // Ovflwbuf
  1642. dz->sbufptr[4] = dz->sampbuf[4] = dz->sampbuf[3] + dz->buflen; // segment-store
  1643. dz->sbufptr[5] = dz->sampbuf[5] = dz->sampbuf[4] + dz->buflen2; // Repeated-segment-store
  1644. dz->sampbuf[6] = dz->sampbuf[5] + dz->buflen2;
  1645. return(FINISHED);
  1646. }
  1647. /******************************** WRITE_AND_RESET_OBUF ********************************/
  1648. int write_and_reset_obuf(int samps_to_write,int *obufpos,dataptr dz)
  1649. {
  1650. int exit_status;
  1651. float *obuf = dz->sampbuf[2], *ovflwbuf = dz->sampbuf[3];
  1652. dz->process = GREV;
  1653. if((exit_status = write_samps(obuf,samps_to_write,dz))<0)
  1654. return(exit_status);
  1655. dz->process = REPEATER;
  1656. memset((char *)obuf,0,dz->buflen * sizeof(float));
  1657. memcpy((char *)obuf,(char *)ovflwbuf,dz->buflen * sizeof(float));
  1658. memset((char *)ovflwbuf,0,dz->buflen * sizeof(float));
  1659. *obufpos -= dz->buflen;
  1660. return FINISHED;
  1661. }
  1662. /******************************** RESET_IBUF_AND_READ ********************************/
  1663. int reset_ibuf_and_read(int *ibufpos,dataptr dz)
  1664. {
  1665. int exit_status;
  1666. float *ibuf = dz->sampbuf[0], *iovflwbuf = dz->sampbuf[1];
  1667. memcpy((char *)ibuf,(char *)iovflwbuf,dz->buflen * sizeof(float)); // Copy input overflow back into ibuf
  1668. memset((char *)iovflwbuf,0,dz->buflen * sizeof(float)); // Set overflow to zero
  1669. if((exit_status = read_samps(iovflwbuf,dz))<0) // Read into overflow
  1670. return(exit_status);
  1671. *ibufpos = dz->buflen; // Reset ibufpos to start of iovflwbuf
  1672. return FINISHED;
  1673. }
  1674. /******************************** NORMALISE_BUFFER ********************************/
  1675. int normalise_buffer(int samplen,dataptr dz)
  1676. {
  1677. double *env = dz->parray[1], maxsamp, thiseval, nexteval, diff, eval;
  1678. float *buf = dz->sampbuf[4];
  1679. int *loc = dz->iparray[0], chans = dz->infile->channels, ch;
  1680. int e, m, k, envsize, maxloc, windowstart, thispos, goalpos, samppos, gap, win_in_buf;
  1681. int needs_enveloping = 0, ethis, enext, done, shortwindow = 0;
  1682. int halfwindow = dz->envwindowlen/2;
  1683. memset((char *)env,0,dz->arraysize * sizeof(double));
  1684. win_in_buf = samplen/dz->envwindowlen; // Number of complete windows in buf
  1685. shortwindow = samplen - (win_in_buf * dz->envwindowlen); // Length of any short window
  1686. // To force the final window to be full-length, we will make the penultimate window the short window
  1687. samppos = 0;
  1688. do {
  1689. samppos = 0;
  1690. for(e = 0; e < win_in_buf;e++) { // For all the normalisable samples, advance by windowlen blocks
  1691. maxsamp = 0.0;
  1692. maxloc = 0;
  1693. for(m=0,k=samppos;m < dz->envwindowlen;m++,k++) { // In each normal window, find the maxsamp
  1694. if(fabs(buf[k]) > maxsamp) {
  1695. maxsamp = fabs(buf[k]);
  1696. maxloc = m;
  1697. }
  1698. }
  1699. samppos += dz->envwindowlen;
  1700. if(e >= dz->arraysize) {
  1701. sprintf(errstr,"envelope arraysize exceeded.\n");
  1702. return PROGRAM_ERROR;
  1703. }
  1704. env[e] = maxsamp; // And store the envelope val
  1705. loc[e] = (maxloc/chans) * chans; // And position of maximum to chan-grp boundary
  1706. }
  1707. if(shortwindow) {
  1708. maxsamp = 0.0;
  1709. maxloc = 0;
  1710. for(m=0,k=samppos;m < shortwindow;m++,k++) {
  1711. if(fabs(buf[k]) > maxsamp) {
  1712. maxsamp = fabs(buf[k]);
  1713. maxloc = m;
  1714. }
  1715. }
  1716. loc[e] = (maxloc/chans) * chans;
  1717. e++;
  1718. }
  1719. envsize = e;
  1720. needs_enveloping = 0;
  1721. for(e = 0;e < envsize;e++) { // Check where signal exceeds max (REPCLIP)
  1722. if(env[e] > REPCLIP) { // and force (re-)envelope to reduce level here
  1723. env[e] = REPCLIP/env[e];
  1724. needs_enveloping = 1; // AND note the re-envelopeing is necessary
  1725. } else // otherwise leave envelope level at 1.0 (no change)
  1726. env[e] = 1.0;
  1727. }
  1728. if(needs_enveloping) { // If enveloping required
  1729. if(env[0] < 1.0) { // If 1st window overloads, do a presmooth
  1730. for(samppos=0;samppos < loc[0];samppos++)
  1731. buf[samppos] = (float)(buf[samppos] * env[0]);
  1732. }
  1733. if(env[envsize-1] < 1.0) { // If last window overloads, do a presmooth
  1734. thispos = loc[envsize-1] + (dz->envwindowlen * (envsize-2));
  1735. goalpos = samplen;
  1736. for(samppos=thispos;samppos < goalpos;samppos++)
  1737. buf[samppos] = (float)(buf[samppos] * env[envsize-1]);
  1738. }
  1739. ethis = -1; // Interpolate the re-envelope vals, in order to envelope the src, in situ
  1740. enext = 0;
  1741. done = 0;
  1742. for(windowstart = 0; windowstart < samplen; windowstart+=dz->envwindowlen) {
  1743. ethis++;
  1744. enext++;
  1745. thiseval = env[ethis];
  1746. nexteval = env[enext];
  1747. if(thiseval < 1.0 && nexteval == 1.0) {
  1748. thispos = windowstart + loc[ethis]; // Interp from maximum in this-window to middle of non-normalised next-window
  1749. goalpos = windowstart + dz->envwindowlen + halfwindow;
  1750. } else if(thiseval == 1.0 && nexteval < 1.0) {
  1751. thispos = windowstart + halfwindow; // Interp from middle of non-normalised this-window to maximum in next
  1752. if(enext >= envsize)
  1753. goalpos = samplen;
  1754. else
  1755. goalpos = windowstart + dz->envwindowlen + loc[enext];
  1756. } else if(thiseval < 1.0 && nexteval < 1.0) {
  1757. thispos = windowstart + loc[ethis]; // Interp from max in this window to max in next
  1758. if(enext >= envsize)
  1759. goalpos = samplen;
  1760. else
  1761. goalpos = windowstart + dz->envwindowlen + loc[enext];
  1762. } else { // (thiseval == 1.0 && nexteval == 1.0) do nothing
  1763. continue;
  1764. }
  1765. samppos = thispos;
  1766. gap = (goalpos - thispos)/chans;
  1767. diff = nexteval - thiseval;
  1768. for(m=0;m < gap;m++) {
  1769. if(samppos >= dz->buflen) {
  1770. done = 1;
  1771. break;
  1772. }
  1773. eval = (double)m/(double)gap;
  1774. eval *= diff;
  1775. eval += thiseval;
  1776. for(ch= 0;ch < chans;ch++) {
  1777. buf[samppos] = (float)(buf[samppos] * eval);
  1778. samppos++;
  1779. }
  1780. }
  1781. if(done)
  1782. break;
  1783. }
  1784. }
  1785. } while(needs_enveloping); // Do this recursively until nothing is too loud
  1786. return FINISHED;
  1787. }
  1788. /****************************** GET_MODE *********************************/
  1789. int get_the_mode_from_cmdline(char *str,dataptr dz)
  1790. {
  1791. char temp[200], *p;
  1792. if(sscanf(str,"%s",temp)!=1) {
  1793. sprintf(errstr,"Cannot read mode of program.\n");
  1794. return(USAGE_ONLY);
  1795. }
  1796. p = temp + strlen(temp) - 1;
  1797. while(p >= temp) {
  1798. if(!isdigit(*p)) {
  1799. fprintf(stderr,"Invalid mode of program entered.\n");
  1800. return(USAGE_ONLY);
  1801. }
  1802. p--;
  1803. }
  1804. if(sscanf(str,"%d",&dz->mode)!=1) {
  1805. fprintf(stderr,"Cannot read mode of program.\n");
  1806. return(USAGE_ONLY);
  1807. }
  1808. if(dz->mode <= 0 || dz->mode > dz->maxmode) {
  1809. fprintf(stderr,"Program mode value [%d] is out of range [1 - %d].\n",dz->mode,dz->maxmode);
  1810. return(USAGE_ONLY);
  1811. }
  1812. dz->mode--; /* CHANGE TO INTERNAL REPRESENTATION OF MODE NO */
  1813. return(FINISHED);
  1814. }
  1815. /****************************** CALC_OUTPUT_DUR *********************************/
  1816. int calc_output_dur(int *dursamps,dataptr dz)
  1817. {
  1818. int exit_status, chans = dz->infile->channels;
  1819. double *segdata = dz->parray[0];
  1820. double stttime, endtime, repeats, delay, seglen, repsdur = 0.0, advance;
  1821. double lastendtime = 0.0, totaldur = 0.0, maxrand = 1.0, srate = (double)dz->infile->srate;
  1822. int n, m;
  1823. if(dz->brksize[REP_RAND]) {
  1824. if((exit_status = get_maxvalue_in_brktable(&maxrand,REP_RAND,dz))<0)
  1825. return exit_status;
  1826. } else if(dz->param[REP_RAND] > 1.0)
  1827. maxrand = dz->param[REP_RAND];
  1828. for(n = 0; n < dz->itemcnt;n+=4) {
  1829. m = n;
  1830. stttime = segdata[m++];
  1831. endtime = segdata[m++];
  1832. repeats = segdata[m++];
  1833. delay = segdata[m++];
  1834. if((advance = stttime - lastendtime) > 0.0) // If we advance in input
  1835. totaldur += advance; // add duration of advance-step to total output duration
  1836. seglen = endtime - stttime;
  1837. switch(dz->mode) {
  1838. case(0): // Find approx duration covered by repeats of segment
  1839. case(2):
  1840. repsdur = (repeats * delay) + seglen;
  1841. break;
  1842. case(1):
  1843. repsdur = (seglen + delay) * repeats;
  1844. break;
  1845. }
  1846. if(maxrand > 1.0) // Allow for max possible randomisation-increase
  1847. repsdur *= maxrand;
  1848. totaldur += repsdur; // and add to total output duration
  1849. lastendtime = endtime;
  1850. }
  1851. if((advance = dz->duration - lastendtime) > 0.0) // IF not yet at end of file
  1852. totaldur += advance; // add duration of step to end-of-file to total output dur
  1853. *dursamps = (int)round(totaldur * srate) * chans;
  1854. return FINISHED;
  1855. }