rotor.c 78 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925
  1. /*
  2. * Copyright (c) 1983-2023 Trevor Wishart and Composers Desktop Project Ltd
  3. * http://www.trevorwishart.co.uk
  4. * http://www.composersdesktop.com
  5. *
  6. This file is part of the CDP System.
  7. The CDP System is free software; you can redistribute it
  8. and/or modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  11. The CDP System is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU Lesser General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public
  16. License along with the CDP System; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18. 02111-1307 USA
  19. *
  20. */
  21. /* SYNTHESIS FROM ROTATING ARMATURES ....
  22. *
  23. * params 0 1 2 3 4 5 6 7 7 8
  24. * params ROT_CNT ROT_PMIN ROT_PMAX ROT_NSTEP ROT_PCYC ROT_TCYC ROT_PHAS ROT_DUR ROT_GSTEP ROT_DOVE
  25. * rotor rotor 1 infile env notecnt minmidi maxmidi maxnotedur protspeed drotspeed inital-phase out_duration step -dx
  26. * rotor rotor 2-3 infile env notecnt minmidi maxmidi maxnotedur protspeed drotspeed inital-phase out_duration -dx
  27. * x in ms
  28. * Take a line with points marked at regular(?) intervals, y (height) determines pitch.
  29. * Rotate the line about centre, so (if clockwise) pitchset falls slightly then more then more,
  30. * until reaches maximum, then rises rapidly rises less etc till all down to same etc
  31. *
  32. * @
  33. *
  34. * @ @
  35. * @
  36. * @ @ @
  37. * @
  38. * @ @ @ @ @ @ @ @ @ ETC
  39. * @
  40. * @ @ @
  41. * @
  42. * @ @
  43. *
  44. * @
  45. * repet-note falling falling chord rising
  46. *
  47. *
  48. *
  49. * Take a line with points marked at regular(?) intervals, "x - minx" determines time.
  50. * Rotate the line about centre.
  51. *
  52. * @
  53. *
  54. * @ @
  55. * @
  56. * @ @ @
  57. * @
  58. * @ @ @ @ @ @ @ @ @ ETC
  59. * 1 2 3 4 5 @
  60. * zero @ @ @
  61. * time @
  62. * slow 1 2 3 4 5 @ @
  63. * tempo zero 12345 12345
  64. * time zero @ zero
  65. * faster time zero time
  66. * very time very
  67. * fast Tutti fast
  68. *
  69. *
  70. *
  71. * infile = waveform to read for synth
  72. * env = envelope to impose on synthd sounds
  73. * notecnt = number of notes in set.
  74. * maxnotestep = max step between notes in slowest set
  75. * protspeed = speed of rotation of pitch line
  76. * drotspeed = speed of rotation of time line = number of pitchlines before we're back to where we started
  77. * initial-phase = (initial) phase difference between pitch and time rotations
  78. * (this will change if rot speeds are different)
  79. * step = time step between each pitch-set in mode 1
  80. * mode 2 uses an extra non-sounding event at end of time row, to determine where
  81. * next timerow begins, hence it dilates and contracts timewise with rotation of time-rotor.
  82. * mode 3 superimposes first note of next row on last note of previous.
  83. */
  84. #include <stdio.h>
  85. #include <stdlib.h>
  86. #include <structures.h>
  87. #include <tkglobals.h>
  88. #include <pnames.h>
  89. #include <filetype.h>
  90. #include <processno.h>
  91. #include <modeno.h>
  92. #include <logic.h>
  93. #include <globcon.h>
  94. #include <cdpmain.h>
  95. #include <math.h>
  96. #include <mixxcon.h>
  97. #include <osbind.h>
  98. #include <standalone.h>
  99. #include <science.h>
  100. #include <ctype.h>
  101. #include <sfsys.h>
  102. #include <string.h>
  103. #include <srates.h>
  104. #define is_stereo is_rectified
  105. #define ROOT2 (1.4142136)
  106. #ifdef unix
  107. #define round(x) lround((x))
  108. #endif
  109. char errstr[2400];
  110. int anal_infiles = 1;
  111. int sloom = 0;
  112. int sloombatch = 0;
  113. const char* cdp_version = "7.0.0";
  114. //CDP LIB REPLACEMENTS
  115. static int check_rotor_param_validity_and_consistency(dataptr dz);
  116. static int setup_rotor_application(dataptr dz);
  117. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  118. static int parse_infile_and_check_type(char **cmdline,dataptr dz);
  119. static int setup_rotor_param_ranges_and_defaults(dataptr dz);
  120. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz);
  121. static int open_the_outfile(dataptr dz);
  122. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  123. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  124. static int establish_application(dataptr dz);
  125. static int initialise_vflags(dataptr dz);
  126. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  127. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  128. static int mark_parameter_types(dataptr dz,aplptr ap);
  129. static int assign_file_data_storage(int infilecnt,dataptr dz);
  130. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  131. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  132. static int get_the_mode_from_cmdline(char *str,dataptr dz);
  133. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  134. static int handle_the_special_data(char *str,dataptr dz);
  135. static int create_rotor_sndbufs(dataptr dz);
  136. static int rotor_param_preprocess(dataptr dz);
  137. static int rotor(dataptr dz) ;
  138. static int write_event(double time,double thispitch,double tabincr,int tabsize,int *obufpos,double normaliser,double line_angle,double pos,dataptr dz);
  139. static int get_event_level(double time,double thispitch,double tabincr,int tabsize,int *obufpos,double *normaliser,double line_angle,double pos,dataptr dz);
  140. static int read_value_from_brkarray(double *env,int *nextind,double *val,double thistime,dataptr dz);
  141. static void time_display(int samps_sent,dataptr dz);
  142. static int write_rotor_samps(float *obuf,int samps_sent,dataptr dz);
  143. /**************************************** MAIN *********************************************/
  144. int main(int argc,char *argv[])
  145. {
  146. int exit_status;
  147. dataptr dz = NULL;
  148. char **cmdline;
  149. int cmdlinecnt;
  150. int n;
  151. //aplptr ap;
  152. int is_launched = FALSE;
  153. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  154. fprintf(stdout,"%s\n",cdp_version);
  155. fflush(stdout);
  156. return 0;
  157. }
  158. /* CHECK FOR SOUNDLOOM */
  159. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  160. sloom = 0;
  161. sloombatch = 1;
  162. }
  163. if(sflinit("cdp")){
  164. sfperror("cdp: initialisation\n");
  165. return(FAILED);
  166. }
  167. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  168. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  169. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  170. return(FAILED);
  171. }
  172. if(!sloom) {
  173. if(argc == 1) {
  174. usage1();
  175. return(FAILED);
  176. } else if(argc == 2) {
  177. usage2(argv[1]);
  178. return(FAILED);
  179. }
  180. }
  181. if(!sloom) {
  182. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  183. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  184. return(FAILED);
  185. }
  186. cmdline = argv;
  187. cmdlinecnt = argc;
  188. if((get_the_process_no(argv[0],dz))<0)
  189. return(FAILED);
  190. cmdline++;
  191. cmdlinecnt--;
  192. dz->maxmode = 3;
  193. if((exit_status = get_the_mode_from_cmdline(cmdline[0],dz))<0) {
  194. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  195. return(exit_status);
  196. }
  197. cmdline++;
  198. cmdlinecnt--;
  199. // setup_particular_application =
  200. if((exit_status = setup_rotor_application(dz))<0) {
  201. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  202. return(FAILED);
  203. }
  204. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  205. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  206. return(FAILED);
  207. }
  208. } else {
  209. //parse_TK_data() =
  210. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  211. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  212. return(exit_status);
  213. }
  214. }
  215. //ap = dz->application;
  216. // parse_infile_and_hone_type() =
  217. if((exit_status = parse_infile_and_check_type(cmdline,dz))<0) {
  218. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  219. return(FAILED);
  220. }
  221. // setup_param_ranges_and_defaults() =
  222. if((exit_status = setup_rotor_param_ranges_and_defaults(dz))<0) {
  223. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  224. return(FAILED);
  225. }
  226. // open_first_infile CDP LIB
  227. if((exit_status = open_first_infile(cmdline[0],dz))<0) {
  228. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  229. return(FAILED);
  230. }
  231. cmdlinecnt--;
  232. cmdline++;
  233. // handle_extra_infiles() : redundant
  234. // handle_outfile() =
  235. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,dz))<0) {
  236. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  237. return(FAILED);
  238. }
  239. // handle_formants() redundant
  240. // handle_formant_quiksearch() redundant
  241. // handle_special_data .....
  242. if((exit_status = handle_the_special_data(cmdline[0],dz))<0) {
  243. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  244. return(FAILED);
  245. }
  246. cmdlinecnt--;
  247. cmdline++;
  248. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  249. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  250. return(FAILED);
  251. }
  252. // check_param_validity_and_consistency....
  253. if((exit_status = check_rotor_param_validity_and_consistency(dz))<0) {
  254. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  255. return(FAILED);
  256. }
  257. if((exit_status = open_the_outfile(dz))<0) {
  258. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  259. return(FAILED);
  260. }
  261. is_launched = TRUE;
  262. dz->bufcnt = 5;
  263. if((dz->sampbuf = (float **)malloc(sizeof(float *) * (dz->bufcnt+1)))==NULL) {
  264. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffers.\n");
  265. return(MEMORY_ERROR);
  266. }
  267. if((dz->sbufptr = (float **)malloc(sizeof(float *) * dz->bufcnt))==NULL) {
  268. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffer pointers.\n");
  269. return(MEMORY_ERROR);
  270. }
  271. for(n = 0;n <dz->bufcnt; n++)
  272. dz->sampbuf[n] = dz->sbufptr[n] = (float *)0;
  273. dz->sampbuf[n] = (float *)0;
  274. if((exit_status = create_rotor_sndbufs(dz))<0) {
  275. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  276. return(FAILED);
  277. }
  278. //param_preprocess ....
  279. if((exit_status = rotor_param_preprocess(dz))<0) {
  280. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  281. return(FAILED);
  282. }
  283. //spec_process_file =
  284. if((exit_status = rotor(dz))<0) {
  285. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  286. return(FAILED);
  287. }
  288. if((exit_status = complete_output(dz))<0) { // CDP LIB
  289. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  290. return(FAILED);
  291. }
  292. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  293. free(dz);
  294. return(SUCCEEDED);
  295. }
  296. /**********************************************
  297. REPLACED CDP LIB FUNCTIONS
  298. **********************************************/
  299. /****************************** SET_PARAM_DATA *********************************/
  300. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  301. {
  302. ap->special_data = (char)special_data;
  303. ap->param_cnt = (char)paramcnt;
  304. ap->max_param_cnt = (char)maxparamcnt;
  305. if(ap->max_param_cnt>0) {
  306. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  307. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  308. return(MEMORY_ERROR);
  309. }
  310. strcpy(ap->param_list,paramlist);
  311. }
  312. return(FINISHED);
  313. }
  314. /****************************** SET_VFLGS *********************************/
  315. int set_vflgs
  316. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  317. {
  318. ap->option_cnt = (char) optcnt; /*RWD added cast */
  319. if(optcnt) {
  320. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  321. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  322. return(MEMORY_ERROR);
  323. }
  324. strcpy(ap->option_list,optlist);
  325. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  326. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  327. return(MEMORY_ERROR);
  328. }
  329. strcpy(ap->option_flags,optflags);
  330. }
  331. ap->vflag_cnt = (char) vflagcnt;
  332. ap->variant_param_cnt = (char) vparamcnt;
  333. if(vflagcnt) {
  334. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  335. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  336. return(MEMORY_ERROR);
  337. }
  338. strcpy(ap->variant_list,varlist);
  339. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  340. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  341. return(MEMORY_ERROR);
  342. }
  343. strcpy(ap->variant_flags,varflags);
  344. }
  345. return(FINISHED);
  346. }
  347. /***************************** APPLICATION_INIT **************************/
  348. int application_init(dataptr dz)
  349. {
  350. int exit_status;
  351. int storage_cnt;
  352. int tipc, brkcnt;
  353. aplptr ap = dz->application;
  354. if(ap->vflag_cnt>0)
  355. initialise_vflags(dz);
  356. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  357. ap->total_input_param_cnt = (char)tipc;
  358. if(tipc>0) {
  359. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  360. return(exit_status);
  361. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  362. return(exit_status);
  363. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  364. return(exit_status);
  365. }
  366. brkcnt = tipc;
  367. //THERE ARE NO INPUTFILE brktables USED IN THIS PROCESS
  368. if(brkcnt>0) {
  369. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  370. return(exit_status);
  371. }
  372. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  373. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  374. return(exit_status);
  375. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  376. return(exit_status);
  377. }
  378. if((exit_status = mark_parameter_types(dz,ap))<0)
  379. return(exit_status);
  380. // establish_infile_constants() replaced by
  381. dz->infilecnt = 1;
  382. //establish_bufptrs_and_extra_buffers():
  383. return(FINISHED);
  384. }
  385. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  386. /* RWD mallo changed to calloc; helps debug verison run as release! */
  387. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  388. {
  389. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  390. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  391. return(MEMORY_ERROR);
  392. }
  393. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  394. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  395. return(MEMORY_ERROR);
  396. }
  397. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  398. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  399. return(MEMORY_ERROR);
  400. }
  401. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  402. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  403. return(MEMORY_ERROR);
  404. }
  405. return(FINISHED);
  406. }
  407. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  408. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  409. {
  410. int n;
  411. for(n=0;n<storage_cnt;n++) {
  412. dz->is_int[n] = (char)0;
  413. dz->no_brk[n] = (char)0;
  414. }
  415. return(FINISHED);
  416. }
  417. /***************************** MARK_PARAMETER_TYPES **************************/
  418. int mark_parameter_types(dataptr dz,aplptr ap)
  419. {
  420. int n, m; /* PARAMS */
  421. for(n=0;n<ap->max_param_cnt;n++) {
  422. switch(ap->param_list[n]) {
  423. case('0'): break; /* dz->is_active[n] = 0 is default */
  424. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  425. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  426. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  427. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  428. default:
  429. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  430. return(PROGRAM_ERROR);
  431. }
  432. } /* OPTIONS */
  433. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  434. switch(ap->option_list[n]) {
  435. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  436. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  437. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  438. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  439. default:
  440. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  441. return(PROGRAM_ERROR);
  442. }
  443. } /* VARIANTS */
  444. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  445. switch(ap->variant_list[n]) {
  446. case('0'): break;
  447. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  448. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  449. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  450. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  451. default:
  452. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  453. return(PROGRAM_ERROR);
  454. }
  455. } /* INTERNAL */
  456. for(n=0,
  457. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  458. switch(ap->internal_param_list[n]) {
  459. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  460. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  461. case('d'): dz->no_brk[m] = (char)1; break;
  462. default:
  463. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  464. return(PROGRAM_ERROR);
  465. }
  466. }
  467. return(FINISHED);
  468. }
  469. /************************ HANDLE_THE_OUTFILE *********************/
  470. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz)
  471. {
  472. int has_extension = 0;
  473. char *filename = (*cmdline)[0], *p;
  474. if(filename[0]=='-' && filename[1]=='f') {
  475. dz->floatsam_output = 1;
  476. dz->true_outfile_stype = SAMP_FLOAT;
  477. filename+= 2;
  478. }
  479. if(!sloom) {
  480. if(file_has_invalid_startchar(filename) || value_is_numeric(filename)) {
  481. sprintf(errstr,"Outfile name %s has invalid start character(s) or looks too much like a number.\n",filename);
  482. return(DATA_ERROR);
  483. }
  484. }
  485. p = filename + strlen(filename);
  486. p--;
  487. while(p != filename) {
  488. if(*p == '.') {
  489. has_extension = 1;
  490. break;
  491. }
  492. p--;
  493. }
  494. strcpy(dz->outfilename,filename);
  495. if(!has_extension)
  496. strcat(dz->outfilename,".wav");
  497. (*cmdline)++;
  498. (*cmdlinecnt)--;
  499. return(FINISHED);
  500. }
  501. /************************ OPEN_THE_OUTFILE *********************/
  502. int open_the_outfile(dataptr dz)
  503. {
  504. int exit_status;
  505. if(dz->is_stereo)
  506. dz->infile->channels = 2;
  507. if((exit_status = create_sized_outfile(dz->outfilename,dz))<0)
  508. return(exit_status);
  509. return(FINISHED);
  510. }
  511. /***************************** ESTABLISH_APPLICATION **************************/
  512. int establish_application(dataptr dz)
  513. {
  514. aplptr ap;
  515. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  516. sprintf(errstr,"establish_application()\n");
  517. return(MEMORY_ERROR);
  518. }
  519. ap = dz->application;
  520. memset((char *)ap,0,sizeof(struct applic));
  521. return(FINISHED);
  522. }
  523. /************************* INITIALISE_VFLAGS *************************/
  524. int initialise_vflags(dataptr dz)
  525. {
  526. int n;
  527. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  528. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  529. return(MEMORY_ERROR);
  530. }
  531. for(n=0;n<dz->application->vflag_cnt;n++)
  532. dz->vflag[n] = FALSE;
  533. return FINISHED;
  534. }
  535. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  536. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  537. {
  538. int n;
  539. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  540. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  541. return(MEMORY_ERROR);
  542. }
  543. for(n=0;n<tipc;n++)
  544. ap->default_val[n] = 0.0;
  545. return(FINISHED);
  546. }
  547. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  548. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  549. {
  550. int n;
  551. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  552. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  553. return(MEMORY_ERROR);
  554. }
  555. for(n=0;n<tipc;n++)
  556. dz->is_active[n] = (char)0;
  557. return(FINISHED);
  558. }
  559. /************************* SETUP_ROTOR_APPLICATION *******************/
  560. int setup_rotor_application(dataptr dz)
  561. {
  562. int exit_status;
  563. aplptr ap;
  564. if((exit_status = establish_application(dz))<0) // GLOBAL
  565. return(FAILED);
  566. ap = dz->application;
  567. // SEE parstruct FOR EXPLANATION of next 2 functions
  568. if(dz->mode == 0)
  569. exit_status = set_param_data(ap,ROTORDAT,9,9,"iDDDIIddD");
  570. else
  571. exit_status = set_param_data(ap,ROTORDAT,9,8,"iDDDIIdd0");
  572. if(exit_status<0)
  573. return(FAILED);
  574. if((exit_status = set_vflgs(ap,"d",1,"d","s",1,0,"0"))<0)
  575. return(FAILED);
  576. // set_legal_infile_structure -->
  577. dz->has_otherfile = FALSE;
  578. // assign_process_logic -->
  579. dz->input_data_type = SNDFILES_ONLY;
  580. dz->process_type = UNEQUAL_SNDFILE;
  581. dz->outfiletype = SNDFILE_OUT;
  582. return application_init(dz); //GLOBAL
  583. }
  584. /************************* PARSE_INFILE_AND_CHECK_TYPE *******************/
  585. int parse_infile_and_check_type(char **cmdline,dataptr dz)
  586. {
  587. int exit_status;
  588. infileptr infile_info;
  589. if(!sloom) {
  590. if((infile_info = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  591. sprintf(errstr,"INSUFFICIENT MEMORY for infile structure to test file data.");
  592. return(MEMORY_ERROR);
  593. } else if((exit_status = cdparse(cmdline[0],infile_info))<0) {
  594. sprintf(errstr,"Failed to parse input file %s\n",cmdline[0]);
  595. return(PROGRAM_ERROR);
  596. } else if(infile_info->filetype != SNDFILE) {
  597. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  598. return(DATA_ERROR);
  599. } else if(infile_info->channels != 1) {
  600. sprintf(errstr,"File %s is not of correct type (must be mono)\n",cmdline[0]);
  601. return(DATA_ERROR);
  602. } else if((exit_status = copy_parse_info_to_main_structure(infile_info,dz))<0) {
  603. sprintf(errstr,"Failed to copy file parsing information\n");
  604. return(PROGRAM_ERROR);
  605. }
  606. free(infile_info);
  607. }
  608. return(FINISHED);
  609. }
  610. /************************* SETUP_ROTOR_PARAM_RANGES_AND_DEFAULTS *******************/
  611. int setup_rotor_param_ranges_and_defaults(dataptr dz)
  612. {
  613. int exit_status;
  614. aplptr ap = dz->application;
  615. // set_param_ranges()
  616. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  617. // NB total_input_param_cnt is > 0 !!!
  618. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  619. return(FAILED);
  620. // get_param_ranges()
  621. ap->lo[ROT_CNT] = 3;
  622. ap->hi[ROT_CNT] = 127;
  623. ap->default_val[ROT_CNT] = 7;
  624. ap->lo[ROT_PMIN] = 0;
  625. ap->hi[ROT_PMIN] = 127;
  626. ap->default_val[ROT_PMIN] = 48;
  627. ap->lo[ROT_PMAX] = 0;
  628. ap->hi[ROT_PMAX] = 127;
  629. ap->default_val[ROT_PMAX] = 72;
  630. ap->lo[ROT_NSTEP] = 0;
  631. ap->hi[ROT_NSTEP] = 4;
  632. ap->default_val[ROT_NSTEP] = .1;
  633. ap->lo[ROT_PCYC] = 4;
  634. ap->hi[ROT_PCYC] = 256;
  635. ap->default_val[ROT_PCYC] = 16;
  636. ap->lo[ROT_TCYC] = 4;
  637. ap->hi[ROT_TCYC] = 256;
  638. ap->default_val[ROT_TCYC] = 16;
  639. ap->lo[ROT_PHAS] = 0;
  640. ap->hi[ROT_PHAS] = 1;
  641. ap->default_val[ROT_PHAS] = 0;
  642. ap->lo[ROT_DUR] = 1;
  643. ap->hi[ROT_DUR] = 32767;
  644. ap->default_val[ROT_DUR] = 20;
  645. if(dz->mode == 0) {
  646. ap->lo[ROT_GSTEP] = .1;
  647. ap->hi[ROT_GSTEP] = 60;
  648. ap->default_val[ROT_GSTEP] = 4;
  649. }
  650. ap->lo[ROT_DOVE] = 0;
  651. ap->hi[ROT_DOVE] = 5;
  652. ap->default_val[ROT_DOVE] = 0;
  653. dz->maxmode = 3;
  654. if(!sloom)
  655. put_default_vals_in_all_params(dz);
  656. return(FINISHED);
  657. }
  658. /********************************* PARSE_SLOOM_DATA *********************************/
  659. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  660. {
  661. int exit_status;
  662. int cnt = 1, infilecnt;
  663. int filesize, insams, inbrksize;
  664. double dummy;
  665. int true_cnt = 0;
  666. //aplptr ap;
  667. while(cnt<=PRE_CMDLINE_DATACNT) {
  668. if(cnt > argc) {
  669. sprintf(errstr,"Insufficient data sent from TK\n");
  670. return(DATA_ERROR);
  671. }
  672. switch(cnt) {
  673. case(1):
  674. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  675. sprintf(errstr,"Cannot read process no. sent from TK\n");
  676. return(DATA_ERROR);
  677. }
  678. break;
  679. case(2):
  680. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  681. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  682. return(DATA_ERROR);
  683. }
  684. if(dz->mode > 0)
  685. dz->mode--;
  686. //setup_particular_application() =
  687. if((exit_status = setup_rotor_application(dz))<0)
  688. return(exit_status);
  689. //ap = dz->application;
  690. break;
  691. case(3):
  692. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  693. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  694. return(DATA_ERROR);
  695. }
  696. if(infilecnt < 1) {
  697. true_cnt = cnt + 1;
  698. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  699. }
  700. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  701. return(exit_status);
  702. break;
  703. case(INPUT_FILETYPE+4):
  704. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  705. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  706. return(DATA_ERROR);
  707. }
  708. break;
  709. case(INPUT_FILESIZE+4):
  710. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  711. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  712. return(DATA_ERROR);
  713. }
  714. dz->insams[0] = filesize;
  715. break;
  716. case(INPUT_INSAMS+4):
  717. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  718. sprintf(errstr,"Cannot read insams sent from TK\n");
  719. return(DATA_ERROR);
  720. }
  721. dz->insams[0] = insams;
  722. break;
  723. case(INPUT_SRATE+4):
  724. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  725. sprintf(errstr,"Cannot read srate sent from TK\n");
  726. return(DATA_ERROR);
  727. }
  728. break;
  729. case(INPUT_CHANNELS+4):
  730. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  731. sprintf(errstr,"Cannot read channels sent from TK\n");
  732. return(DATA_ERROR);
  733. }
  734. break;
  735. case(INPUT_STYPE+4):
  736. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  737. sprintf(errstr,"Cannot read stype sent from TK\n");
  738. return(DATA_ERROR);
  739. }
  740. break;
  741. case(INPUT_ORIGSTYPE+4):
  742. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  743. sprintf(errstr,"Cannot read origstype sent from TK\n");
  744. return(DATA_ERROR);
  745. }
  746. break;
  747. case(INPUT_ORIGRATE+4):
  748. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  749. sprintf(errstr,"Cannot read origrate sent from TK\n");
  750. return(DATA_ERROR);
  751. }
  752. break;
  753. case(INPUT_MLEN+4):
  754. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  755. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  756. return(DATA_ERROR);
  757. }
  758. break;
  759. case(INPUT_DFAC+4):
  760. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  761. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  762. return(DATA_ERROR);
  763. }
  764. break;
  765. case(INPUT_ORIGCHANS+4):
  766. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  767. sprintf(errstr,"Cannot read origchans sent from TK\n");
  768. return(DATA_ERROR);
  769. }
  770. break;
  771. case(INPUT_SPECENVCNT+4):
  772. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  773. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  774. return(DATA_ERROR);
  775. }
  776. dz->specenvcnt = dz->infile->specenvcnt;
  777. break;
  778. case(INPUT_WANTED+4):
  779. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  780. sprintf(errstr,"Cannot read wanted sent from TK\n");
  781. return(DATA_ERROR);
  782. }
  783. break;
  784. case(INPUT_WLENGTH+4):
  785. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  786. sprintf(errstr,"Cannot read wlength sent from TK\n");
  787. return(DATA_ERROR);
  788. }
  789. break;
  790. case(INPUT_OUT_CHANS+4):
  791. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  792. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  793. return(DATA_ERROR);
  794. }
  795. break;
  796. /* RWD these chanegs to samps - tk will have to deal with that! */
  797. case(INPUT_DESCRIPTOR_BYTES+4):
  798. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  799. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  800. return(DATA_ERROR);
  801. }
  802. break;
  803. case(INPUT_IS_TRANSPOS+4):
  804. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  805. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  806. return(DATA_ERROR);
  807. }
  808. break;
  809. case(INPUT_COULD_BE_TRANSPOS+4):
  810. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  811. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  812. return(DATA_ERROR);
  813. }
  814. break;
  815. case(INPUT_COULD_BE_PITCH+4):
  816. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  817. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  818. return(DATA_ERROR);
  819. }
  820. break;
  821. case(INPUT_DIFFERENT_SRATES+4):
  822. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  823. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  824. return(DATA_ERROR);
  825. }
  826. break;
  827. case(INPUT_DUPLICATE_SNDS+4):
  828. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  829. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  830. return(DATA_ERROR);
  831. }
  832. break;
  833. case(INPUT_BRKSIZE+4):
  834. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  835. sprintf(errstr,"Cannot read brksize sent from TK\n");
  836. return(DATA_ERROR);
  837. }
  838. if(inbrksize > 0) {
  839. switch(dz->input_data_type) {
  840. case(WORDLIST_ONLY):
  841. break;
  842. case(PITCH_AND_PITCH):
  843. case(PITCH_AND_TRANSPOS):
  844. case(TRANSPOS_AND_TRANSPOS):
  845. dz->tempsize = inbrksize;
  846. break;
  847. case(BRKFILES_ONLY):
  848. case(UNRANGED_BRKFILE_ONLY):
  849. case(DB_BRKFILES_ONLY):
  850. case(ALL_FILES):
  851. case(ANY_NUMBER_OF_ANY_FILES):
  852. if(dz->extrabrkno < 0) {
  853. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  854. return(DATA_ERROR);
  855. }
  856. if(dz->brksize == NULL) {
  857. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  858. return(PROGRAM_ERROR);
  859. }
  860. dz->brksize[dz->extrabrkno] = inbrksize;
  861. break;
  862. default:
  863. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  864. dz->input_data_type);
  865. return(PROGRAM_ERROR);
  866. }
  867. break;
  868. }
  869. break;
  870. case(INPUT_NUMSIZE+4):
  871. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  872. sprintf(errstr,"Cannot read numsize sent from TK\n");
  873. return(DATA_ERROR);
  874. }
  875. break;
  876. case(INPUT_LINECNT+4):
  877. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  878. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  879. return(DATA_ERROR);
  880. }
  881. break;
  882. case(INPUT_ALL_WORDS+4):
  883. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  884. sprintf(errstr,"Cannot read all_words sent from TK\n");
  885. return(DATA_ERROR);
  886. }
  887. break;
  888. case(INPUT_ARATE+4):
  889. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  890. sprintf(errstr,"Cannot read arate sent from TK\n");
  891. return(DATA_ERROR);
  892. }
  893. break;
  894. case(INPUT_FRAMETIME+4):
  895. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  896. sprintf(errstr,"Cannot read frametime sent from TK\n");
  897. return(DATA_ERROR);
  898. }
  899. dz->frametime = (float)dummy;
  900. break;
  901. case(INPUT_WINDOW_SIZE+4):
  902. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  903. sprintf(errstr,"Cannot read window_size sent from TK\n");
  904. return(DATA_ERROR);
  905. }
  906. break;
  907. case(INPUT_NYQUIST+4):
  908. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  909. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  910. return(DATA_ERROR);
  911. }
  912. break;
  913. case(INPUT_DURATION+4):
  914. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  915. sprintf(errstr,"Cannot read duration sent from TK\n");
  916. return(DATA_ERROR);
  917. }
  918. break;
  919. case(INPUT_MINBRK+4):
  920. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  921. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  922. return(DATA_ERROR);
  923. }
  924. break;
  925. case(INPUT_MAXBRK+4):
  926. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  927. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  928. return(DATA_ERROR);
  929. }
  930. break;
  931. case(INPUT_MINNUM+4):
  932. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  933. sprintf(errstr,"Cannot read minnum sent from TK\n");
  934. return(DATA_ERROR);
  935. }
  936. break;
  937. case(INPUT_MAXNUM+4):
  938. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  939. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  940. return(DATA_ERROR);
  941. }
  942. break;
  943. default:
  944. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  945. return(PROGRAM_ERROR);
  946. }
  947. cnt++;
  948. }
  949. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  950. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  951. return(DATA_ERROR);
  952. }
  953. if(true_cnt)
  954. cnt = true_cnt;
  955. *cmdlinecnt = 0;
  956. while(cnt < argc) {
  957. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  958. return(exit_status);
  959. cnt++;
  960. }
  961. return(FINISHED);
  962. }
  963. /********************************* GET_TK_CMDLINE_WORD *********************************/
  964. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  965. {
  966. if(*cmdlinecnt==0) {
  967. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  968. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  969. return(MEMORY_ERROR);
  970. }
  971. } else {
  972. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  973. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  974. return(MEMORY_ERROR);
  975. }
  976. }
  977. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  978. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  979. return(MEMORY_ERROR);
  980. }
  981. strcpy((*cmdline)[*cmdlinecnt],q);
  982. (*cmdlinecnt)++;
  983. return(FINISHED);
  984. }
  985. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  986. int assign_file_data_storage(int infilecnt,dataptr dz)
  987. {
  988. int exit_status;
  989. int no_sndfile_system_files = FALSE;
  990. dz->infilecnt = infilecnt;
  991. if((exit_status = allocate_filespace(dz))<0)
  992. return(exit_status);
  993. if(no_sndfile_system_files)
  994. dz->infilecnt = 0;
  995. return(FINISHED);
  996. }
  997. /************************* redundant functions: to ensure libs compile OK *******************/
  998. int assign_process_logic(dataptr dz)
  999. {
  1000. return(FINISHED);
  1001. }
  1002. void set_legal_infile_structure(dataptr dz)
  1003. {}
  1004. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  1005. {
  1006. return(FINISHED);
  1007. }
  1008. int setup_internal_arrays_and_array_pointers(dataptr dz)
  1009. {
  1010. return(FINISHED);
  1011. }
  1012. int establish_bufptrs_and_extra_buffers(dataptr dz)
  1013. {
  1014. return(FINISHED);
  1015. }
  1016. int read_special_data(char *str,dataptr dz)
  1017. {
  1018. return(FINISHED);
  1019. }
  1020. int inner_loop
  1021. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  1022. {
  1023. return(FINISHED);
  1024. }
  1025. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1026. {
  1027. return(FINISHED);
  1028. }
  1029. /******************************** USAGE1 ********************************/
  1030. int usage1()
  1031. {
  1032. usage2("rotor");
  1033. return(USAGE_ONLY);
  1034. }
  1035. /**************************** CHECK_ROTOR_PARAM_VALIDITY_AND_CONSISTENCY *****************************/
  1036. int check_rotor_param_validity_and_consistency(dataptr dz)
  1037. {
  1038. if(!dz->brksize[ROT_PMIN] && !dz->brksize[ROT_PMAX]) {
  1039. if(flteq(dz->param[ROT_PMIN],dz->param[ROT_PMAX])) {
  1040. sprintf(errstr,"Zero pitchrange (%lf to %lf) specified.\n",dz->param[ROT_PMIN],dz->param[ROT_PMAX]);
  1041. return(DATA_ERROR);
  1042. } else if(dz->param[ROT_PMIN] > dz->param[ROT_PMAX]) {
  1043. fprintf(stdout,"WARNING: Inverted or pitchrange (%lf to %lf) specified.\n",dz->param[ROT_PMIN],dz->param[ROT_PMAX]);
  1044. fflush(stdout);
  1045. }
  1046. }
  1047. if(dz->vflag[0])
  1048. dz->is_stereo = 1;
  1049. else
  1050. dz->is_stereo = 0;
  1051. return FINISHED;
  1052. }
  1053. /********************************************************************************************/
  1054. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1055. {
  1056. if(!strcmp(prog_identifier_from_cmdline,"rotor")) dz->process = ROTOR;
  1057. else {
  1058. sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  1059. return(USAGE_ONLY);
  1060. }
  1061. return(FINISHED);
  1062. }
  1063. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  1064. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  1065. {
  1066. int n;
  1067. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1068. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  1069. return(MEMORY_ERROR);
  1070. }
  1071. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1072. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  1073. return(MEMORY_ERROR);
  1074. }
  1075. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1076. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  1077. return(MEMORY_ERROR);
  1078. }
  1079. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1080. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  1081. return(MEMORY_ERROR);
  1082. }
  1083. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1084. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  1085. return(MEMORY_ERROR);
  1086. }
  1087. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1088. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  1089. return(MEMORY_ERROR);
  1090. }
  1091. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1092. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  1093. return(MEMORY_ERROR);
  1094. }
  1095. for(n=0;n<brkcnt;n++) {
  1096. dz->brk[n] = NULL;
  1097. dz->brkptr[n] = NULL;
  1098. dz->brkinit[n] = 0;
  1099. dz->brksize[n] = 0;
  1100. }
  1101. return(FINISHED);
  1102. }
  1103. /******************************** USAGE2 ********************************/
  1104. int usage2(char *str)
  1105. {
  1106. if(!strcmp(str,"rotor")) {
  1107. fprintf(stderr,
  1108. "USAGE:\n"
  1109. "rotor rotor 1 fi fo env cnt minp maxp step prot trot phas dur gstp [-ddove] [-s]\n"
  1110. "rotor rotor 2-3 fi fo env cnt minp maxp step prot trot phas dur [-ddove] [-s]\n"
  1111. "\n"
  1112. "Generate note-sets that grow and shrink in pitch-range and speed (and spatial-width).\n"
  1113. "\n"
  1114. "Mode 1: Note-set start-times determined by param \"gstp\".\n"
  1115. "Mode 2: Next Note-set start-time, depends on spacings WITHIN current set.\n"
  1116. "Mode 3: First event of next note-set overlaid on last event of previous set.\n"
  1117. "\n"
  1118. "FI File to be read at different speeds to generate output events.\n"
  1119. " (should start and end at sample value 0.0, OR use \"dove\")\n"
  1120. "FO Output file(can be mono or stereo).\n"
  1121. "ENV Envelope to be imposed over output events.\n"
  1122. " Envelope duration determines duration of all events.\n"
  1123. "CNT Number of events in each (changing) set (Range 3 to 127).\n"
  1124. "MINP Minimum (MIDI) pitch of events (Range 0 to 127).\n"
  1125. "MAXP Maximum (MIDI) pitch of events (Range 0 to 127).\n"
  1126. "STEP Maximum timestep between event-onsets (Range 0 to 4 secs).\n"
  1127. "PROT Number of notesets before pitch-sequence returns to orig (Range 4 to 256).\n"
  1128. "TROT Number of speeds, before speed returns to original (Range 4 to 256).\n"
  1129. "PHAS Initial phase difference between prot and trot (range 0 - 1).\n"
  1130. "DUR Duration of output to generate (Range 1 to 32767).\n"
  1131. "GSTP (Mode 1 only) timestep between each note-group (Range 1 to 60).\n"
  1132. "DOVE Size (mS) of start/end dovetails of insound (Range 0 to 5).\n"
  1133. "\n"
  1134. "-s Stereo output: output grows and shrinks in spatial width.\n");
  1135. } else
  1136. fprintf(stdout,"Unknown option '%s'\n",str);
  1137. return(USAGE_ONLY);
  1138. }
  1139. int usage3(char *str1,char *str2)
  1140. {
  1141. fprintf(stderr,"Insufficient parameters on command line.\n");
  1142. return(USAGE_ONLY);
  1143. }
  1144. /****************************** GET_MODE *********************************/
  1145. int get_the_mode_from_cmdline(char *str,dataptr dz)
  1146. {
  1147. char temp[200], *p;
  1148. if(sscanf(str,"%s",temp)!=1) {
  1149. sprintf(errstr,"Cannot read mode of program.\n");
  1150. return(USAGE_ONLY);
  1151. }
  1152. p = temp + strlen(temp) - 1;
  1153. while(p >= temp) {
  1154. if(!isdigit(*p)) {
  1155. fprintf(stderr,"Invalid mode of program entered.\n");
  1156. return(USAGE_ONLY);
  1157. }
  1158. p--;
  1159. }
  1160. if(sscanf(str,"%d",&dz->mode)!=1) {
  1161. fprintf(stderr,"Cannot read mode of program.\n");
  1162. return(USAGE_ONLY);
  1163. }
  1164. if(dz->mode <= 0 || dz->mode > dz->maxmode) {
  1165. fprintf(stderr,"Program mode value [%d] is out of range [1 - %d].\n",dz->mode,dz->maxmode);
  1166. return(USAGE_ONLY);
  1167. }
  1168. dz->mode--; /* CHANGE TO INTERNAL REPRESENTATION OF MODE NO */
  1169. return(FINISHED);
  1170. }
  1171. /**************************** HANDLE_THE_SPECIAL_DATA ****************************/
  1172. int handle_the_special_data(char *str,dataptr dz)
  1173. {
  1174. FILE *fp;
  1175. double dummy, lasttime = 0.0;
  1176. char temp[200], *p;
  1177. int istime = 1;
  1178. int cnt = 0;
  1179. if((fp = fopen(str,"r"))==NULL) {
  1180. sprintf(errstr,"Cannot open file %s to read envelope data.\n",str);
  1181. return(DATA_ERROR);
  1182. }
  1183. while(fgets(temp,200,fp)!=NULL) {
  1184. p = temp;
  1185. while(isspace(*p))
  1186. p++;
  1187. if(*p == ';' || *p == ENDOFSTR) // Allow comments in file
  1188. continue;
  1189. while(get_float_from_within_string(&p,&dummy)) {
  1190. if(istime) {
  1191. if(cnt == 0) {
  1192. if(dummy != 0.0) {
  1193. sprintf(errstr,"Initial time in data in file %s must be zero.\n",str);
  1194. return(DATA_ERROR);
  1195. }
  1196. } else {
  1197. if(dummy <= lasttime) {
  1198. sprintf(errstr,"Times do not advance between %lf and %lf in file %s\n",lasttime,dummy,str);
  1199. return(DATA_ERROR);
  1200. }
  1201. }
  1202. lasttime = dummy;
  1203. } else if(dummy > 1.0 || dummy < 0.0) {
  1204. sprintf(errstr,"Found envelope value (%lf) out of range (0 to 1) in file %s\n",dummy,str);
  1205. return(DATA_ERROR);
  1206. }
  1207. istime = !istime;
  1208. cnt++;
  1209. }
  1210. }
  1211. if(cnt == 0) {
  1212. sprintf(errstr,"No data found in file %s\n",str);
  1213. return(DATA_ERROR);
  1214. }
  1215. if(!EVEN(cnt)) {
  1216. sprintf(errstr,"Data not paired correctly in file %s\n",str);
  1217. return(DATA_ERROR);
  1218. }
  1219. if(cnt < 4) {
  1220. sprintf(errstr,"Insufficient data found in file %s : Needs at least 2 time-value pairs.\n",str);
  1221. return(DATA_ERROR);
  1222. }
  1223. dz->frametime = (float)lasttime; // Remember duration of envelope
  1224. dz->rampbrksize = (int)round(dz->frametime * dz->infile->srate); // Remember duration of envelope in samples
  1225. if((dz->parray = (double **)malloc(sizeof(double *)))==NULL) {
  1226. sprintf(errstr,"INSUFFICIENT MEMORY to store transposition data.\n");
  1227. return(MEMORY_ERROR);
  1228. }
  1229. if((dz->parray[0] = (double *)malloc(cnt * sizeof(double)))==NULL) {
  1230. sprintf(errstr,"INSUFFICIENT MEMORY to store transposition data.\n");
  1231. return(MEMORY_ERROR);
  1232. }
  1233. cnt = 0;
  1234. fseek(fp,0,0);
  1235. while(fgets(temp,200,fp)!=NULL) {
  1236. p = temp;
  1237. while(isspace(*p))
  1238. p++;
  1239. if(*p == ';' || *p == ENDOFSTR) // Allow comments in file
  1240. continue;
  1241. while(get_float_from_within_string(&p,&dummy)) {
  1242. dz->parray[0][cnt] = dummy;
  1243. cnt++;
  1244. }
  1245. }
  1246. fclose(fp);
  1247. dz->itemcnt = cnt;
  1248. return FINISHED;
  1249. }
  1250. /*************************** CREATE_ROTOR_SNDBUFS **************************/
  1251. int create_rotor_sndbufs(dataptr dz)
  1252. {
  1253. int n, exit_status;
  1254. int bigbufsize, inbufsize, evbufsize, maxrotstepsamps, maxrotcnt;
  1255. double maxrotstep, maxrotcntd;
  1256. if(dz->sbufptr == 0 || dz->sampbuf==0) {
  1257. sprintf(errstr,"buffer pointers not allocated: create_sndbufs()\n");
  1258. return(PROGRAM_ERROR);
  1259. }
  1260. if(dz->brksize[ROT_NSTEP]) {
  1261. if((exit_status = get_maxvalue_in_brktable(&maxrotstep,ROT_NSTEP,dz))<0)
  1262. return exit_status;
  1263. } else
  1264. maxrotstep = dz->param[ROT_NSTEP];
  1265. if(dz->brksize[ROT_CNT]) { // Output may baktrak, noteset to noteset
  1266. if((exit_status = get_maxvalue_in_brktable(&maxrotcntd,ROT_CNT,dz))<0)
  1267. return exit_status;
  1268. maxrotcnt = (int)round(maxrotcntd);
  1269. } else
  1270. maxrotcnt = dz->iparam[ROT_CNT];
  1271. maxrotstepsamps = (int)ceil(maxrotstep * dz->infile->srate); // maximum size of note
  1272. dz->buflen = maxrotcnt * maxrotstepsamps; // maximum size of noteset
  1273. if(dz->is_stereo)
  1274. dz->buflen *= 2;
  1275. inbufsize = dz->insams[0] + 1; // Add wrap-around point
  1276. evbufsize = dz->rampbrksize; // Store size of envelope, in samples
  1277. evbufsize += 2; // 1 for wraparound, 1 for safety!!
  1278. if(dz->is_stereo)
  1279. bigbufsize = inbufsize + (evbufsize * 4) + (dz->buflen * 2); // In mode 0, may need to baktrak, but never more than 1 complete (max)setlen
  1280. else
  1281. bigbufsize = inbufsize + (evbufsize * 3) + (dz->buflen * 2); // Need space for outbuf & overflowbuf
  1282. if((dz->bigbuf = (float *)malloc(bigbufsize * sizeof(float))) == NULL) {
  1283. sprintf(errstr,"INSUFFICIENT MEMORY to create sound buffers.\n");
  1284. return(PROGRAM_ERROR);
  1285. }
  1286. // MONO
  1287. // obuf ovflwbuf eventbuf envelopebuf inbuf
  1288. // 0 1 2 3 4
  1289. // |-------|------------------|------------------|------------------|------------|
  1290. //
  1291. // buflen evbufsize evbufsize evbufsize insams[0]
  1292. //
  1293. // STEREO
  1294. // obuf ovflwbuf eventbuf envelopebuf inbuf
  1295. // 0 1 2 3 4
  1296. // |-------|------------------------------------|------------------|------------------|------------|
  1297. // buflen evbufsize * 2 evbufsize evbufsize insams[0]
  1298. //
  1299. //
  1300. n = 0;
  1301. dz->sbufptr[n] = dz->sampbuf[n] = dz->bigbuf;
  1302. n++; // 0 = Output buffer
  1303. dz->sbufptr[n] = dz->sampbuf[n] = dz->sampbuf[n-1] + (dz->buflen * 2); // size buflen * 2
  1304. n++; // 1 = overflow buffer
  1305. if(dz->is_stereo) // size evbufsize * outchans
  1306. dz->sbufptr[n] = dz->sampbuf[n] = dz->sampbuf[n-1] + (evbufsize * 2);
  1307. else
  1308. dz->sbufptr[n] = dz->sampbuf[n] = dz->sampbuf[n-1] + evbufsize; // 2 = created event
  1309. n++; // size evbufsize
  1310. dz->sbufptr[n] = dz->sampbuf[n] = dz->sampbuf[n-1] + evbufsize; // 3 = envelope of event
  1311. n++; // size evbufsize
  1312. dz->sbufptr[n] = dz->sampbuf[n] = dz->sampbuf[n-1] + evbufsize; // 4 = insndbuf
  1313. return(FINISHED);
  1314. }
  1315. /************************************* ROTOR_PARAM_PREPROCESS ***********************************
  1316. *
  1317. * (1) Read input file to buffer, withg wraparound point, for reading as a waveform table.
  1318. * (2) Convert input envelope to a sample scale array in another buffer.
  1319. */
  1320. int rotor_param_preprocess(dataptr dz)
  1321. {
  1322. int exit_status;
  1323. double *env = dz->parray[0];
  1324. int n, m;
  1325. double srate = (double)dz->infile->srate, val, thistime;
  1326. int origbuflen = dz->buflen, nextind, dovecnt;
  1327. float *ibuf = dz->sampbuf[4];
  1328. float *ebuf = dz->sampbuf[3];
  1329. dz->buflen = dz->insams[0]; // Read input sound to ibuf
  1330. if((exit_status = read_samps(ibuf,dz))<0)
  1331. return(exit_status);
  1332. if(dz->param[ROT_DOVE] > 0) {
  1333. dovecnt = (int)round(dz->param[ROT_DOVE] * MS_TO_SECS * dz->infile->srate);
  1334. if(dovecnt * 2 >= dz->buflen) {
  1335. sprintf(errstr,"Dovetails too large for input sound.\n");
  1336. return DATA_ERROR;
  1337. }
  1338. for(n= 0;n < dovecnt; n++) { // Dovetail start
  1339. val = (double)n/(double)dovecnt;
  1340. ibuf[n] = (float)(ibuf[n] * val);
  1341. } // Dovetail end
  1342. for(n= dz->buflen - 1,m = 0;m < dovecnt; n--,m++) {
  1343. val = (double)m/(double)dovecnt;
  1344. ibuf[n] = (float)(ibuf[n] * val);
  1345. }
  1346. }
  1347. ibuf[dz->buflen] = 0; // Wrap-around zero-point
  1348. dz->buflen = origbuflen;
  1349. nextind = 2; // Read input envelope array into a sample-scale array in a buffer
  1350. for(n = 0; n < dz->rampbrksize; n++) {
  1351. thistime = (double)n/srate;
  1352. if((exit_status = read_value_from_brkarray(env,&nextind,&val,thistime,dz))<0)
  1353. return exit_status;
  1354. ebuf[n] = (float)val;
  1355. }
  1356. ebuf[n] = 0.0f; // Wrap-around zero point
  1357. return FINISHED;
  1358. }
  1359. /**************************** READ_VALUE_FROM_BRKARRAY *****************************/
  1360. int read_value_from_brkarray(double *env,int *nextind,double *val,double time,dataptr dz)
  1361. {
  1362. double thistim, nexttim, thisval, nextval, valdiff, timdiff, timfrac;
  1363. nexttim = env[*nextind];
  1364. while(time > nexttim) {
  1365. if((*nextind += 2) >= dz->itemcnt) {
  1366. sprintf(errstr, "Overshot end of envelope brktable while converting to sample-buffer.\n");
  1367. return PROGRAM_ERROR;
  1368. }
  1369. nexttim = env[*nextind];
  1370. }
  1371. thistim = env[*nextind - 2];
  1372. thisval = env[*nextind - 1];
  1373. nextval = env[*nextind + 1];
  1374. valdiff = nextval - thisval;
  1375. timdiff = nexttim - thistim;
  1376. timfrac = (time - thistim)/timdiff;
  1377. valdiff *= timfrac;
  1378. *val = thisval + valdiff;
  1379. return FINISHED;
  1380. }
  1381. /**************************** ROTOR *****************************/
  1382. int rotor(dataptr dz)
  1383. {
  1384. int exit_status, pitch_orient = 1;
  1385. int obufpos, ovflwsize;
  1386. float *obuf = dz->sampbuf[0];
  1387. int stepcnt, notecnt = dz->iparam[ROT_CNT], kk, tsets_per_cycle; // If there are 5 positions before line returns to orig position.
  1388. double drotspeed, protspeed, maxtime, duration, maxrange, centre, total_time, local_time, line_angle, p_line_angle;
  1389. double pitchrange, halfrange, rangebot, thispitch, timestep, thispos, normaliser = 0.0;
  1390. int m, n;
  1391. int tabsize = dz->insams[0];
  1392. double tabincr = (double)tabsize/(double)dz->infile->srate; // tabincr to read table once per second, i.e. at 1Hz
  1393. int ochans = 1;
  1394. if(dz->is_stereo)
  1395. ochans++;
  1396. ovflwsize = dz->rampbrksize * ochans;
  1397. stepcnt = notecnt - 1; // e.g. with 5 notes, there are 4 gaps
  1398. duration = dz->param[ROT_DUR]; // Total duration of output
  1399. dz->tempsize = (int)round(duration * dz->infile->srate) * ochans; // Establish scale for loom progress_bar
  1400. // INITIALISE CONSTANTS
  1401. for(kk=0;kk<2;kk++) {
  1402. memset((char *)obuf,0,((dz->buflen * 2) + ovflwsize) * sizeof(float));
  1403. obufpos = 0;
  1404. total_time = 0.0;
  1405. line_angle = 0.0;
  1406. dz->total_samps_written = 0;
  1407. if(kk == 0)
  1408. time_display(dz->total_samps_written,dz);
  1409. p_line_angle = dz->iparam[ROT_PHAS] * TWOPI; // Set initla phase of pitch-rotor
  1410. if(dz->brksize[ROT_TCYC]) {
  1411. if((exit_status = read_value_from_brktable(total_time,ROT_TCYC,dz))<0)
  1412. return(exit_status);
  1413. }
  1414. tsets_per_cycle = dz->iparam[ROT_TCYC]; // If there are 5 positions before line returns to orig position.
  1415. drotspeed= 1.0/tsets_per_cycle; // then there is (r=)1/5th of a rotation per line-set.
  1416. drotspeed *= TWOPI; // Convert to radians.
  1417. if(dz->brksize[ROT_PCYC]) {
  1418. if((exit_status = read_value_from_brktable(total_time,ROT_PCYC,dz))<0)
  1419. return(exit_status);
  1420. }
  1421. protspeed = 1.0/dz->iparam[ROT_PCYC]; // How much of a cycle per note-set
  1422. protspeed *= TWOPI; // Convert to radians.
  1423. if(dz->brksize[ROT_PMAX]) {
  1424. if((exit_status = read_value_from_brktable(total_time,ROT_PMAX,dz))<0)
  1425. return(exit_status);
  1426. }
  1427. if(dz->brksize[ROT_PMIN]) {
  1428. if((exit_status = read_value_from_brktable(total_time,ROT_PMIN,dz))<0)
  1429. return(exit_status);
  1430. }
  1431. maxrange = dz->param[ROT_PMAX] - dz->param[ROT_PMIN];
  1432. centre = dz->param[ROT_PMIN] + maxrange/2.0; // Set initial pitch-range params
  1433. if(dz->brksize[ROT_NSTEP]) {
  1434. if((exit_status = read_value_from_brktable(total_time,ROT_NSTEP,dz))<0)
  1435. return(exit_status);
  1436. }
  1437. maxtime = dz->param[ROT_NSTEP]; // Set initial maximum timestep between notes.
  1438. if(kk == 0) {
  1439. fprintf(stdout,"INFO: Checking output level.\n");
  1440. fflush(stdout);
  1441. } else {
  1442. if(sloom)
  1443. fprintf(stdout,"INFO: Writing output.\n");
  1444. else
  1445. fprintf(stdout,"\nINFO: Writing output.\n");
  1446. fflush(stdout);
  1447. }
  1448. while(total_time < duration) {
  1449. for(m = 0; m < tsets_per_cycle;m++) {
  1450. local_time = 0.0;
  1451. timestep = fabs(maxtime * cos(line_angle)); // Time-step to next event when line is tilted at angle
  1452. pitchrange = maxrange * sin(p_line_angle); // Range shrunk (or inverted) by sin-function.
  1453. halfrange = pitchrange/2.0; // If inverted, halfrange is -ve
  1454. halfrange *= pitch_orient; // Inverts range on passing through 2PI
  1455. rangebot = centre - halfrange; // and "rangebot" is at top
  1456. for(n = 0;n < stepcnt; n++) {
  1457. // CACULATE PITCH OF EVENT FROM ROTATING ARM, AND POSITION ON ARM
  1458. thispos = (double)n/(double)stepcnt; // relative position in range (normalised 0-1)
  1459. thispitch = thispos * pitchrange; // but "thispitch" here is -ve
  1460. thispitch *= pitch_orient;
  1461. thispitch += rangebot; // So true pitch is subtracted from top of range
  1462. // WRITE OUTPUT EVENT
  1463. if(kk == 0) {
  1464. if((exit_status = get_event_level(total_time+local_time,thispitch,tabincr,tabsize,&obufpos,&normaliser,line_angle,thispos,dz))<0) // Check output level
  1465. return exit_status;
  1466. } else {
  1467. if((exit_status = write_event(total_time+local_time,thispitch,tabincr,tabsize,&obufpos,normaliser,line_angle,thispos,dz))<0) // Write all events except last
  1468. return exit_status;
  1469. }
  1470. // ADVANCE TIME, VIA TIME-ROTATOR
  1471. local_time += timestep;
  1472. }
  1473. // WRITE FINAL EVENT OF TIME-SET
  1474. thispos = (double)n/(double)stepcnt;
  1475. thispitch = thispos * pitchrange;
  1476. thispitch *= pitch_orient;
  1477. thispitch += rangebot;
  1478. if(kk == 0) {
  1479. if((exit_status = get_event_level(total_time+local_time,thispitch,tabincr,tabsize,&obufpos,&normaliser,line_angle,thispos,dz))<0) // Check output level
  1480. return exit_status;
  1481. } else {
  1482. if((exit_status = write_event(total_time+local_time,thispitch,tabincr,tabsize,&obufpos,normaliser,line_angle,thispos,dz))<0) // Write last_event
  1483. return exit_status;
  1484. }
  1485. // AT END OF A COMPLETE SET, Read any time-varying params
  1486. // PITCH ROTOR CONTINUES TO ROTATE
  1487. p_line_angle += protspeed; // Advance pitch-rotator angle
  1488. if(p_line_angle >= TWOPI) { // If pitchrotor cycle completed
  1489. if(dz->brksize[ROT_PCYC]) {
  1490. if((exit_status = read_value_from_brktable(total_time,ROT_PCYC,dz))<0)
  1491. return(exit_status);
  1492. protspeed = 1.0/dz->iparam[ROT_PCYC]; // How much of a cycle per note-set
  1493. protspeed *= TWOPI; // Convert to radians.
  1494. }
  1495. p_line_angle -= TWOPI;
  1496. pitch_orient = -pitch_orient;
  1497. }
  1498. if(p_line_angle < PI/2.0 || p_line_angle >= 3 * PI/2.0)
  1499. pitch_orient = 1;
  1500. else
  1501. pitch_orient = -1;
  1502. // Update any (other) timer-varying params, at end of a noteset
  1503. if(dz->brksize[ROT_PMIN] || dz->brksize[ROT_PMAX]) {
  1504. if(dz->brksize[ROT_PMIN]) {
  1505. if((exit_status = read_value_from_brktable(total_time,ROT_PMIN,dz))<0)
  1506. return(exit_status);
  1507. }
  1508. if(dz->brksize[ROT_PMAX]) {
  1509. if((exit_status = read_value_from_brktable(total_time,ROT_PMAX,dz))<0)
  1510. return(exit_status);
  1511. }
  1512. maxrange = dz->param[ROT_PMAX] - dz->param[ROT_PMIN];
  1513. centre = dz->param[ROT_PMIN] + maxrange/2.0;
  1514. }
  1515. if(dz->brksize[ROT_NSTEP]) {
  1516. if((exit_status = read_value_from_brktable(total_time,ROT_NSTEP,dz))<0)
  1517. return(exit_status);
  1518. maxtime = dz->param[ROT_NSTEP];
  1519. }
  1520. if(dz->brksize[ROT_TCYC]) {
  1521. if((exit_status = read_value_from_brktable(total_time,ROT_TCYC,dz))<0)
  1522. return(exit_status);
  1523. // Cannot alter the tsets_per_cycle inside this loop (do it after exiting loop, below)
  1524. drotspeed= 1.0/dz->iparam[ROT_TCYC];
  1525. drotspeed *= TWOPI;
  1526. }
  1527. if((line_angle += drotspeed) >= TWOPI)
  1528. line_angle -= TWOPI;
  1529. // locate start of next TSET
  1530. switch(dz->mode) {
  1531. case(0):
  1532. if(dz->brksize[ROT_GSTEP]) {
  1533. if((exit_status = read_value_from_brktable(total_time,ROT_GSTEP,dz))<0)
  1534. return(exit_status);
  1535. } // Get step to next note-set as input param
  1536. total_time += dz->param[ROT_GSTEP];
  1537. break;
  1538. case(1): // All events have already been written
  1539. total_time += local_time + timestep;
  1540. break;
  1541. case(2): // Keep group time where last group was placed
  1542. total_time += local_time;
  1543. break; // (1st event of next set superimposed on last event this set)
  1544. }
  1545. if(total_time >= duration)
  1546. break;
  1547. }
  1548. // Add the end of a complete rotation of groups-of-notesets, read any time-varying time-rotation data
  1549. if(dz->brksize[ROT_TCYC]) {
  1550. if((exit_status = read_value_from_brktable(total_time,ROT_TCYC,dz))<0)
  1551. return(exit_status);
  1552. tsets_per_cycle = dz->iparam[ROT_TCYC];
  1553. // We already know drotspeed from reading table above
  1554. }
  1555. }
  1556. if(kk == 0) {
  1557. if(obufpos > 0) {
  1558. for(n=0;n<obufpos;n++) {
  1559. if(fabs(obuf[n]) > normaliser)
  1560. normaliser = fabs(obuf[n]);
  1561. }
  1562. }
  1563. normaliser = 0.95/normaliser;
  1564. } else {
  1565. if(obufpos > 0) {
  1566. if(normaliser < 1.0) {
  1567. for(n=0;n<obufpos;n++)
  1568. obuf[n] = (float)(obuf[n] * normaliser);
  1569. }
  1570. if((exit_status = write_rotor_samps(obuf,obufpos,dz))<0)
  1571. return(exit_status);
  1572. }
  1573. }
  1574. }
  1575. return FINISHED;
  1576. }
  1577. /******************************************* WRITE_EVENT *******************************/
  1578. int write_event(double time,double thispitch,double tabincr,int tabsize,int *obufpos,double normaliser,double line_angle,double pos,dataptr dz)
  1579. {
  1580. int exit_status;
  1581. float *obuf = dz->sampbuf[0];
  1582. float *nbuf = dz->sampbuf[2];
  1583. float *ebuf = dz->sampbuf[3]; // Create envelope of length of required event, at srate
  1584. float *ibuf = dz->sampbuf[4];
  1585. double frq = miditohz(thispitch);
  1586. int eventsamps = dz->rampbrksize,n,k,ovflwsize;
  1587. double tabpos = 0.0, frac, diff, relpos, reldist, temp, lpos, rpos,thisval;
  1588. int thispos, nextpos, bufpos;
  1589. int ochans = 1;
  1590. if(dz->is_stereo)
  1591. ochans++;
  1592. ovflwsize = dz->rampbrksize * ochans;
  1593. tabincr *= frq; // Frq-related table-read increment
  1594. for(n = 0; n< eventsamps;n++) {
  1595. thispos = (int)floor(tabpos); // Read input sample by interpolation
  1596. nextpos = thispos+1; // with incr determined by pitch/frq
  1597. frac = tabpos - thispos;
  1598. diff = ibuf[nextpos] - ibuf[thispos];
  1599. diff *= frac;
  1600. thisval = ibuf[thispos] + diff;
  1601. nbuf[n] = (float)(thisval * ebuf[n]); // Scale by input envelope
  1602. tabpos += tabincr;
  1603. if(tabpos >= tabsize)
  1604. tabpos -= tabsize;
  1605. }
  1606. bufpos = (int)round(time * dz->infile->srate) * ochans;
  1607. bufpos -= dz->total_samps_written;
  1608. while(bufpos >= (dz->buflen * 2) + ovflwsize) { // In case bufpos jumps ahead beyond buffer
  1609. if(normaliser < 1.0) { // Only write (1) buflen if we've also filled the overflow buffer
  1610. for(k=0;k<dz->buflen;k++) { // so that we can potentially backtrack over the buflen
  1611. obuf[k] = (float)(obuf[k] * normaliser);
  1612. }
  1613. }
  1614. if((exit_status = write_rotor_samps(obuf,dz->buflen,dz))<0)
  1615. return(exit_status);
  1616. memcpy((char *)obuf,(char *)(obuf+dz->buflen),(ovflwsize + dz->buflen) * sizeof(float));
  1617. memset((char *)(obuf + dz->buflen + ovflwsize),0,dz->buflen * sizeof(float));
  1618. bufpos -= dz->buflen;
  1619. }
  1620. if(dz->is_stereo) { // Change position range from (normalised) 0 to 1
  1621. pos *= 2.0; // to 0 to 2
  1622. pos -= 1.0; // to -1 to +1
  1623. pos *= cos(line_angle); // Scale according to line angle : (-1 to 1) at cos(0)==1 --> (-1 to 1)
  1624. if(pos < 0) // (-1 to 1) at cos(PI/2)==0 --> (0 to 0) squeezed to centre
  1625. relpos = -pos; // (-1 to 1) at cos(PI)==-1 --> (1 to -1) range inverted : ETC
  1626. else // Do hole-in-middle compensation
  1627. relpos = pos;
  1628. temp = 1.0 + (relpos * relpos);
  1629. reldist = ROOT2 / sqrt(temp);
  1630. temp = (pos + 1.0) / 2.0;
  1631. rpos = temp * reldist;
  1632. lpos = (1.0 - temp ) * reldist;
  1633. for(n = 0; n< eventsamps;n++) { // Add new event into output stream
  1634. if(bufpos >= (dz->buflen * 2) + ovflwsize) {
  1635. if(normaliser < 1.0) {
  1636. for(k=0;k<dz->buflen;k++) {
  1637. obuf[k] = (float)(obuf[k] * normaliser);
  1638. }
  1639. }
  1640. if((exit_status = write_rotor_samps(obuf,dz->buflen,dz))<0)
  1641. return(exit_status);
  1642. memcpy((char *)obuf,(char *)(obuf+dz->buflen),(ovflwsize + dz->buflen) * sizeof(float));
  1643. memset((char *)(obuf + dz->buflen + ovflwsize),0,dz->buflen * sizeof(float));
  1644. bufpos -= dz->buflen;
  1645. }
  1646. obuf[bufpos] = (float)(obuf[bufpos] + (nbuf[n] * lpos));
  1647. bufpos++;
  1648. obuf[bufpos] = (float)(obuf[bufpos] + (nbuf[n] * rpos));
  1649. bufpos++;
  1650. }
  1651. } else {
  1652. for(n = 0; n< eventsamps;n++) { // Add new event into output stream
  1653. if(bufpos >= (dz->buflen * 2) + ovflwsize) {
  1654. if(normaliser < 1.0) {
  1655. for(k=0;k<dz->buflen;k++)
  1656. obuf[k] = (float)(obuf[k] * normaliser);
  1657. }
  1658. if((exit_status = write_rotor_samps(obuf,dz->buflen,dz))<0)
  1659. return(exit_status);
  1660. memcpy((char *)obuf,(char *)(obuf+dz->buflen),(ovflwsize + dz->buflen) * sizeof(float));
  1661. memset((char *)(obuf + dz->buflen + ovflwsize),0,dz->buflen * sizeof(float));
  1662. bufpos -= dz->buflen;
  1663. }
  1664. obuf[bufpos] = (float)(obuf[bufpos] + nbuf[n]);
  1665. bufpos++;
  1666. }
  1667. }
  1668. *obufpos = bufpos;
  1669. return FINISHED;
  1670. }
  1671. /******************************************* GET_EVENT_LEVEL *******************************/
  1672. int get_event_level(double time,double thispitch,double tabincr,int tabsize,int *obufpos,double *normaliser,double line_angle,double pos,dataptr dz)
  1673. {
  1674. float *obuf = dz->sampbuf[0];
  1675. float *nbuf = dz->sampbuf[2];
  1676. float *ebuf = dz->sampbuf[3]; // Create envelope of length of required event, at srate
  1677. float *ibuf = dz->sampbuf[4];
  1678. double frq = miditohz(thispitch);
  1679. int eventsamps = dz->rampbrksize,n,k, ovflwsize;
  1680. double tabpos = 0.0, frac, diff, thisval, relpos, temp, reldist, rpos,lpos;
  1681. int thispos, nextpos, bufpos;
  1682. int ochans = 1;
  1683. if(dz->is_stereo)
  1684. ochans++;
  1685. ovflwsize = dz->rampbrksize * ochans;
  1686. tabincr *= frq; // Frq-related table-read increment
  1687. for(n = 0; n< eventsamps;n++) {
  1688. thispos = (int)floor(tabpos); // Read input sample by interpolation
  1689. nextpos = thispos+1; // with incr determined by pitch/frq
  1690. frac = tabpos - thispos;
  1691. diff = ibuf[nextpos] - ibuf[thispos];
  1692. diff *= frac;
  1693. thisval = ibuf[thispos] + diff;
  1694. nbuf[n] = (float)(thisval * ebuf[n]); // Scale by input envelope
  1695. tabpos += tabincr;
  1696. if(tabpos >= tabsize)
  1697. tabpos -= tabsize;
  1698. }
  1699. bufpos = (int)round(time * dz->infile->srate) * ochans;
  1700. bufpos -= dz->total_samps_written;
  1701. while(bufpos >= (dz->buflen * 2) + ovflwsize) { // In case bufpos jumps ahead beyond buffer
  1702. for(k=0;k<dz->buflen;k++) {
  1703. if(fabs(obuf[k]) > *normaliser)
  1704. *normaliser = fabs(obuf[k]);
  1705. }
  1706. dz->total_samps_written += dz->buflen;
  1707. time_display(dz->total_samps_written,dz);
  1708. memcpy((char *)obuf,(char *)(obuf+dz->buflen),(ovflwsize + dz->buflen) * sizeof(float));
  1709. memset((char *)(obuf + dz->buflen + ovflwsize),0,dz->buflen * sizeof(float));
  1710. bufpos -= dz->buflen;
  1711. }
  1712. if(dz->is_stereo) {
  1713. pos *= 2.0; // to 0 to 2
  1714. pos -= 1.0; // to -1 to +1
  1715. pos *= cos(line_angle); // Scale according to line angle : (-1 to 1) at cos(0)==1 --> (-1 to 1)
  1716. if(pos < 0) // (-1 to 1) at cos(PI/2)==0 --> (0 to 0) squeezed to centre
  1717. relpos = -pos; // (-1 to 1) at cos(PI)==-1 --> (1 to -1) range inverted : ETC
  1718. else // Do hole-in-middle compensation
  1719. relpos = pos;
  1720. temp = 1.0 + (relpos * relpos);
  1721. reldist = ROOT2 / sqrt(temp);
  1722. temp = (pos + 1.0) / 2.0;
  1723. rpos = temp * reldist;
  1724. lpos = (1.0 - temp ) * reldist;
  1725. for(n = 0; n< eventsamps;n++) { // Add new event into output stream
  1726. if(bufpos >= (dz->buflen * 2) + ovflwsize) {
  1727. for(k=0;k<dz->buflen;k++) {
  1728. if(fabs(obuf[k]) > *normaliser)
  1729. *normaliser = fabs(obuf[k]);
  1730. }
  1731. dz->total_samps_written += dz->buflen;
  1732. time_display(dz->total_samps_written,dz);
  1733. memcpy((char *)obuf,(char *)(obuf+dz->buflen),(ovflwsize + dz->buflen) * sizeof(float));
  1734. memset((char *)(obuf + dz->buflen + ovflwsize),0,dz->buflen * sizeof(float));
  1735. bufpos -= dz->buflen;
  1736. }
  1737. obuf[bufpos] = (float)(obuf[bufpos] + (nbuf[n] * lpos));
  1738. bufpos++;
  1739. obuf[bufpos] = (float)(obuf[bufpos] + (nbuf[n] * rpos));
  1740. bufpos++;
  1741. }
  1742. } else {
  1743. for(n = 0; n< eventsamps;n++) { // Add new event into output stream
  1744. if(bufpos >= (dz->buflen * 2) + ovflwsize) {
  1745. for(k=0;k<dz->buflen;k++) {
  1746. if(fabs(obuf[k]) > *normaliser)
  1747. *normaliser = fabs(obuf[k]);
  1748. }
  1749. dz->total_samps_written += dz->buflen;
  1750. time_display(dz->total_samps_written,dz);
  1751. memcpy((char *)obuf,(char *)(obuf+dz->buflen),(ovflwsize + dz->buflen) * sizeof(float));
  1752. memset((char *)(obuf + dz->buflen + ovflwsize),0,dz->buflen * sizeof(float));
  1753. bufpos -= dz->buflen;
  1754. }
  1755. obuf[bufpos] = (float)(obuf[bufpos] + nbuf[n]);
  1756. bufpos++;
  1757. }
  1758. }
  1759. *obufpos = bufpos;
  1760. return FINISHED;
  1761. }
  1762. /******************************* TIME_DISPLAY **************************/
  1763. void time_display(int samps_sent,dataptr dz)
  1764. {
  1765. if(sloom)
  1766. dz->process = MTOS;
  1767. display_virtual_time(samps_sent,dz);
  1768. if(sloom)
  1769. dz->process = ROTOR;
  1770. }
  1771. /******************************* WRITE_ROTOR_SAMPS **************************/
  1772. int write_rotor_samps(float *obuf,int samps_sent,dataptr dz)
  1773. {
  1774. int exit_status;
  1775. if(sloom) // Ensures correct setting of progress bar
  1776. dz->process = MTOS;
  1777. if((exit_status = write_samps(obuf,samps_sent,dz))<0)
  1778. return(exit_status);
  1779. if(sloom)
  1780. dz->process = ROTOR;
  1781. return FINISHED;
  1782. }