crystal.c 103 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581
  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. /* IDea here is to place a crystal in 3d space,
  22. * Then to rotate crystal in 3d space, reading the position of the vertices as they appear projected onto the x-y plane.
  23. *
  24. * If the original coordinates of a point (on a sphere) are x.y.z
  25. * then a rotation about the z-axis of X radians is given by matrix
  26. *
  27. * cos(X) sin(x) 0
  28. * -sin(X) cos(X) 0
  29. * 0 0 1
  30. *
  31. * This creates new points (x',y',z') thus
  32. *
  33. * x' = cos(X)*x + sin(X)*y + 0*z
  34. * y' = -sin(X)*x + cos(X)*y + 0*z
  35. * z' = 0*x + 0*y + 1*z
  36. *
  37. *
  38. * For a rotation around the y axis of Y radians, matrix is
  39. *
  40. * cos(Y) 0 sin(Y)
  41. * 0 1 0
  42. * -sin(Y) 0 cos(Y)
  43. *
  44. * This creates new points (x',y',z') thus
  45. *
  46. * x' = cos(Y)*x + 0*y + sin(Y)*z
  47. * y' = 0*x + 1*y + 0*z
  48. * z' = -sin(Y)*x + 0*y + cos(Y)*z
  49. *
  50. * Calculate X and Y from the angular rotation speeds, and timestep, and apply them successively.
  51. *
  52. *
  53. * params pos(xyz) 0 1 2 3 4 5 6 7 8 9
  54. * params of each vertex ROTRATE-A ROTRATE-B TIMESTEP DURATION LOWPITCH HIPITCH TIMEWIDTH CHANS FILT-PASS FILT_STOP
  55. * crystal rotate inf [inf2 ...] outf special rotA rotB tstep dur pl ph tw ch fp fs
  56. *
  57. */
  58. #include <stdio.h>
  59. #include <stdlib.h>
  60. #include <structures.h>
  61. #include <tkglobals.h>
  62. #include <pnames.h>
  63. #include <filetype.h>
  64. #include <processno.h>
  65. #include <modeno.h>
  66. #include <logic.h>
  67. #include <globcon.h>
  68. #include <cdpmain.h>
  69. #include <math.h>
  70. #include <mixxcon.h>
  71. #include <osbind.h>
  72. #include <standalone.h>
  73. #include <science.h>
  74. #include <ctype.h>
  75. #include <sfsys.h>
  76. #include <string.h>
  77. #include <srates.h>
  78. // PARAMS
  79. // ARRAYS
  80. #define ORIG_VTX_DATA (0)
  81. #define VERTEX_DATA (1)
  82. #define ENV_DATA (2)
  83. #define CRY_DEN1 (3)
  84. #define CRY_DEN2 (4)
  85. #define CRY_CN (5)
  86. #define CRY_S1 (6)
  87. #define CRY_E1 (7)
  88. #define CRY_S2 (8)
  89. #define CRY_E2 (9)
  90. //SND BUFFERS
  91. //RWD OBUF and IBUF already defined in standalpone.h. So we need local names here
  92. #define THISOBUF (0) // Output (multichan) buf
  93. #define OVFLWBUF (1) // Overflow
  94. #define TRNSBUF (2) // Trnasposed (by delay-process) sound buf
  95. #define ENVBUF (3) // Enveloped-sound buf
  96. #define FSBUF (4) // Filter or stack buffer
  97. #define EBUF (5) // Raw-envelope buf
  98. #define THISIBUF (6) // Input buf (or start of several input buffers)
  99. // INTERNAL CONSTANTS
  100. #define CRY_MINFBWIDTH (50.0) // Minimum gap between pass and stop bands of filter
  101. #define CRY_LBF (200) // Param used in filter definitions
  102. #define MAX_PROPORTION_8UP_IN_STAK (0.66) // Max amount of 8va transposed version mixed into staks
  103. #define MAXCRYSLEVEL (0.95)
  104. // At present, transposed sounds normalised to 0.95.
  105. // If this results in stacks becoming less loud than non-stacks, change this to e.g. 0.5 ???
  106. #define ALL_CHANS (8) // Channel count for 8-chan output
  107. #define SIGNAL_TO_LEFT (0)
  108. #define SIGNAL_TO_RIGHT (1)
  109. #define SAFETY (16)
  110. #define CRY_DOVE (0.002) // 2mS dovetail of start and end of srcs
  111. #define CRY_STKFAC (2.0) // Relation between the slope for introducing the 8va up transpos in the stack
  112. // and the slope for introducing the two-oct transposition.
  113. // e.g. if 8va slope is 0.5, 2_8va slope is 1
  114. #define ROOT2 (1.4142136)
  115. #define DOTEST 1
  116. #define stackpeak total_windows
  117. #define no_of_vertices itemcnt
  118. #define envdatalen ringsize
  119. #define outcnt could_be_transpos
  120. #ifdef unix
  121. #define round(x) lround((x))
  122. #endif
  123. char errstr[2400];
  124. int anal_infiles = 1;
  125. int sloom = 0;
  126. int sloombatch = 0;
  127. const char* cdp_version = "7.0.0";
  128. //CDP LIB REPLACEMENTS
  129. static int check_crystal_param_validity_and_consistency(dataptr dz);
  130. static int setup_crystal_application(dataptr dz);
  131. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  132. static int parse_infile_and_check_type(char **cmdline,dataptr dz);
  133. static int setup_crystal_param_ranges_and_defaults(dataptr dz);
  134. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz);
  135. static int open_the_outfile(dataptr dz);
  136. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  137. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  138. static int establish_application(dataptr dz);
  139. static int initialise_vflags(dataptr dz);
  140. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  141. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  142. static int mark_parameter_types(dataptr dz,aplptr ap);
  143. static int assign_file_data_storage(int infilecnt,dataptr dz);
  144. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  145. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  146. static int get_the_mode_from_cmdline(char *str,dataptr dz);
  147. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  148. static int handle_the_special_data(char *str,dataptr dz);
  149. static int create_crystal_sndbufs(dataptr dz);
  150. static int crystal_param_preprocess(dataptr dz);
  151. //static int get_event_level(double time,double thispitch,double tabincr,int tabsize,int *obufpos,double *normaliser,double line_angle,double pos,dataptr dz);
  152. static int read_value_from_brkarray(double *env,int *nextind,double *val,double thistime,dataptr dz);
  153. static int stack_enveld_snd(double closeness, dataptr dz);
  154. static int envelope_sound(int do_normalise,dataptr dz);
  155. static int get_vectorlen(double *vectorlen,double x,double y,double z);
  156. static void do_lphp_filter(dataptr dz);
  157. static void initialise_filter_coeffs_lphp(dataptr dz);
  158. static void calculate_filter_poles_lphp(double signd,int filter_order,dataptr dz);
  159. static int allocate_internal_params_lphp(dataptr dz);
  160. static int establish_order_of_filter(dataptr dz);
  161. static int setup_lphp_filter(dataptr dz);
  162. static int filter_sound(double z, dataptr dz);
  163. static int delay_transpose_input_sound(double midipitch, int n, dataptr dz);
  164. static int calculate_pitch_and_time_params(double *midipitch,int *monosamptime,double x,double y,double eventtime,dataptr dz);
  165. static int crystal_rotate(dataptr dz);
  166. static int set_the_legal_internalparam_structure(aplptr ap);
  167. static int handle_the_extra_infiles(char ***cmdline,int *cmdlinecnt,dataptr dz);
  168. static void doperm(int *perm,int permlen);
  169. static void hinsert(int m,int t,int *perm,int permlen);
  170. static void hprefix(int m,int *perm,int permlen);
  171. static void hshuflup(int k,int *perm,int permlen);
  172. static int calculate_time_params(int *monosamptime,double x,double eventtime,dataptr dz) ;
  173. static int check_position_of_event_group_in_output_buf(int passno,double *maxlevel,int *maxwrite,int minsamptime,double normaliser,dataptr dz);
  174. static int write_sound_into_output_buf(int monosamptime,int minsamptime,double x,int eightrot,int *maxwrite,dataptr dz);
  175. static void rotate_vertex(double *x,double *y,double *z,double rotation_in_xy_plane,double rotation_in_xz_plane,int vertexno,double eventtime,int *warning);
  176. static void pancalc(double position,double *leftgain,double *rightgain);
  177. static void dovetail(int dovelen, dataptr dz);
  178. static int write_rotated_crystal_sound(float *obuf,int maxwrite, dataptr dz);
  179. /**************************************** MAIN *********************************************/
  180. int main(int argc,char *argv[])
  181. {
  182. int exit_status;
  183. dataptr dz = NULL;
  184. char **cmdline;
  185. int cmdlinecnt;
  186. int n;
  187. // aplptr ap;
  188. int is_launched = FALSE;
  189. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  190. fprintf(stdout,"%s\n",cdp_version);
  191. fflush(stdout);
  192. return 0;
  193. }
  194. /* CHECK FOR SOUNDLOOM */
  195. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  196. sloom = 0;
  197. sloombatch = 1;
  198. }
  199. if(sflinit("cdp")){
  200. sfperror("cdp: initialisation\n");
  201. return(FAILED);
  202. }
  203. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  204. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  205. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  206. return(FAILED);
  207. }
  208. if(!sloom) {
  209. if(argc == 1) {
  210. usage1();
  211. return(FAILED);
  212. } else if(argc == 2) {
  213. usage2(argv[1]);
  214. return(FAILED);
  215. }
  216. }
  217. if(!sloom) {
  218. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  219. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  220. return(FAILED);
  221. }
  222. cmdline = argv;
  223. cmdlinecnt = argc;
  224. if((get_the_process_no(argv[0],dz))<0)
  225. return(FAILED);
  226. cmdline++;
  227. cmdlinecnt--;
  228. dz->maxmode = 10;
  229. if((exit_status = get_the_mode_from_cmdline(cmdline[0],dz))<0) {
  230. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  231. return(exit_status);
  232. }
  233. cmdline++;
  234. cmdlinecnt--;
  235. // setup_particular_application =
  236. if((exit_status = setup_crystal_application(dz))<0) {
  237. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  238. return(FAILED);
  239. }
  240. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  241. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  242. return(FAILED);
  243. }
  244. } else {
  245. //parse_TK_data() =
  246. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  247. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  248. return(exit_status);
  249. }
  250. }
  251. // ap = dz->application;
  252. // parse_infile_and_hone_type() =
  253. if((exit_status = parse_infile_and_check_type(cmdline,dz))<0) {
  254. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  255. return(FAILED);
  256. }
  257. // setup_param_ranges_and_defaults() =
  258. if((exit_status = setup_crystal_param_ranges_and_defaults(dz))<0) {
  259. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  260. return(FAILED);
  261. }
  262. // open_first_infile CDP LIB
  263. if((exit_status = open_first_infile(cmdline[0],dz))<0) {
  264. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  265. return(FAILED);
  266. }
  267. cmdlinecnt--;
  268. cmdline++;
  269. if((exit_status = handle_the_extra_infiles(&cmdline,&cmdlinecnt,dz))<0) {
  270. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  271. return(FAILED);
  272. }
  273. // handle_outfile() =
  274. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,dz))<0) {
  275. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  276. return(FAILED);
  277. }
  278. // handle_formants() redundant
  279. // handle_formant_quiksearch() redundant
  280. // handle_special_data .....
  281. if((exit_status = handle_the_special_data(cmdline[0],dz))<0) {
  282. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  283. return(FAILED);
  284. }
  285. cmdlinecnt--;
  286. cmdline++;
  287. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  288. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  289. return(FAILED);
  290. }
  291. // check_param_validity_and_consistency....
  292. if((exit_status = check_crystal_param_validity_and_consistency(dz))<0) {
  293. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  294. return(FAILED);
  295. }
  296. if((exit_status = open_the_outfile(dz))<0) {
  297. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  298. return(FAILED);
  299. }
  300. is_launched = TRUE;
  301. dz->bufcnt = 6;
  302. dz->bufcnt += dz->infilecnt;
  303. if((dz->sampbuf = (float **)malloc(sizeof(float *) * (dz->bufcnt+1)))==NULL) {
  304. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffers.\n");
  305. return(MEMORY_ERROR);
  306. }
  307. if((dz->sbufptr = (float **)malloc(sizeof(float *) * dz->bufcnt))==NULL) {
  308. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffer pointers.\n");
  309. return(MEMORY_ERROR);
  310. }
  311. for(n = 0;n <dz->bufcnt; n++)
  312. dz->sampbuf[n] = dz->sbufptr[n] = (float *)0;
  313. dz->sampbuf[n] = (float *)0;
  314. if((exit_status = create_crystal_sndbufs(dz))<0) {
  315. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  316. return(FAILED);
  317. }
  318. //param_preprocess ....
  319. if((exit_status = crystal_param_preprocess(dz))<0) {
  320. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  321. return(FAILED);
  322. }
  323. //spec_process_file =
  324. if((exit_status = crystal_rotate(dz))<0) {
  325. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  326. return(FAILED);
  327. }
  328. if((exit_status = complete_output(dz))<0) { // CDP LIB
  329. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  330. return(FAILED);
  331. }
  332. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  333. free(dz);
  334. return(SUCCEEDED);
  335. }
  336. /**********************************************
  337. REPLACED CDP LIB FUNCTIONS
  338. **********************************************/
  339. /****************************** SET_PARAM_DATA *********************************/
  340. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  341. {
  342. ap->special_data = (char)special_data;
  343. ap->param_cnt = (char)paramcnt;
  344. ap->max_param_cnt = (char)maxparamcnt;
  345. if(ap->max_param_cnt>0) {
  346. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  347. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  348. return(MEMORY_ERROR);
  349. }
  350. strcpy(ap->param_list,paramlist);
  351. }
  352. return(FINISHED);
  353. }
  354. /****************************** SET_VFLGS *********************************/
  355. int set_vflgs
  356. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  357. {
  358. ap->option_cnt = (char) optcnt; /*RWD added cast */
  359. if(optcnt) {
  360. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  361. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  362. return(MEMORY_ERROR);
  363. }
  364. strcpy(ap->option_list,optlist);
  365. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  366. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  367. return(MEMORY_ERROR);
  368. }
  369. strcpy(ap->option_flags,optflags);
  370. }
  371. ap->vflag_cnt = (char) vflagcnt;
  372. ap->variant_param_cnt = (char) vparamcnt;
  373. if(vflagcnt) {
  374. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  375. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  376. return(MEMORY_ERROR);
  377. }
  378. strcpy(ap->variant_list,varlist);
  379. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  380. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  381. return(MEMORY_ERROR);
  382. }
  383. strcpy(ap->variant_flags,varflags);
  384. }
  385. return(FINISHED);
  386. }
  387. /***************************** APPLICATION_INIT **************************/
  388. int application_init(dataptr dz)
  389. {
  390. int exit_status;
  391. int storage_cnt;
  392. int tipc, brkcnt;
  393. aplptr ap = dz->application;
  394. if(ap->vflag_cnt>0)
  395. initialise_vflags(dz);
  396. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  397. ap->total_input_param_cnt = (char)tipc;
  398. if(tipc>0) {
  399. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  400. return(exit_status);
  401. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  402. return(exit_status);
  403. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  404. return(exit_status);
  405. }
  406. brkcnt = tipc;
  407. //THERE ARE NO INPUTFILE brktables USED IN THIS PROCESS
  408. if(brkcnt>0) {
  409. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  410. return(exit_status);
  411. }
  412. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  413. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  414. return(exit_status);
  415. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  416. return(exit_status);
  417. }
  418. if((exit_status = mark_parameter_types(dz,ap))<0)
  419. return(exit_status);
  420. // establish_infile_constants() replaced by
  421. dz->infilecnt = -1; // Flags 1 or more infiles
  422. return(exit_status);
  423. //establish_bufptrs_and_extra_buffers():
  424. return(FINISHED);
  425. }
  426. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  427. /* RWD mallo changed to calloc; helps debug verison run as release! */
  428. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  429. {
  430. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  431. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  432. return(MEMORY_ERROR);
  433. }
  434. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  435. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  436. return(MEMORY_ERROR);
  437. }
  438. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  439. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  440. return(MEMORY_ERROR);
  441. }
  442. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  443. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  444. return(MEMORY_ERROR);
  445. }
  446. return(FINISHED);
  447. }
  448. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  449. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  450. {
  451. int n;
  452. for(n=0;n<storage_cnt;n++) {
  453. dz->is_int[n] = (char)0;
  454. dz->no_brk[n] = (char)0;
  455. }
  456. return(FINISHED);
  457. }
  458. /***************************** MARK_PARAMETER_TYPES **************************/
  459. int mark_parameter_types(dataptr dz,aplptr ap)
  460. {
  461. int n, m; /* PARAMS */
  462. for(n=0;n<ap->max_param_cnt;n++) {
  463. switch(ap->param_list[n]) {
  464. case('0'): break; /* dz->is_active[n] = 0 is default */
  465. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  466. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  467. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  468. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  469. default:
  470. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  471. return(PROGRAM_ERROR);
  472. }
  473. } /* OPTIONS */
  474. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  475. switch(ap->option_list[n]) {
  476. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  477. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  478. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  479. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  480. default:
  481. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  482. return(PROGRAM_ERROR);
  483. }
  484. } /* VARIANTS */
  485. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  486. switch(ap->variant_list[n]) {
  487. case('0'): break;
  488. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  489. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  490. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  491. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  492. default:
  493. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  494. return(PROGRAM_ERROR);
  495. }
  496. } /* INTERNAL */
  497. for(n=0,
  498. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  499. switch(ap->internal_param_list[n]) {
  500. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  501. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  502. case('d'): dz->no_brk[m] = (char)1; break;
  503. default:
  504. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  505. return(PROGRAM_ERROR);
  506. }
  507. }
  508. return(FINISHED);
  509. }
  510. /************************ HANDLE_THE_OUTFILE *********************/
  511. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz)
  512. {
  513. int has_extension = 0, k;
  514. char *filename = (*cmdline)[0], *p;
  515. if(filename[0]=='-' && filename[1]=='f') {
  516. dz->floatsam_output = 1;
  517. dz->true_outfile_stype = SAMP_FLOAT;
  518. filename+= 2;
  519. }
  520. if(!sloom) {
  521. if(file_has_invalid_startchar(filename) || value_is_numeric(filename)) {
  522. sprintf(errstr,"Outfile name %s has invalid start character(s) or looks too much like a number.\n",filename);
  523. return(DATA_ERROR);
  524. }
  525. }
  526. p = filename + strlen(filename);
  527. p--;
  528. while(p != filename) {
  529. if(*p == '.') {
  530. has_extension = 1;
  531. break;
  532. }
  533. p--;
  534. }
  535. strcpy(dz->outfilename,filename);
  536. if(!has_extension)
  537. strcat(dz->outfilename,".wav");
  538. if(dz->mode == 9) {
  539. k = strlen(dz->outfilename);
  540. if(sloom)
  541. k -= 5; // No need to store "0.wav"
  542. else
  543. k -= 4; // No need to store ".wav"
  544. if((dz->wordstor = (char **)malloc(1 * sizeof(char *)))==NULL) {
  545. sprintf(errstr,"INSUFFICIENT MEMORY to store generic name of outputfile (A).\n");
  546. return(MEMORY_ERROR);
  547. }
  548. if((dz->wordstor[0] = (char *)malloc((k+1) * sizeof(char)))==NULL) { // need extra space for ENDOFSTRING
  549. sprintf(errstr,"INSUFFICIENT MEMORY to store generic name of outputfile (B).\n");
  550. return(MEMORY_ERROR);
  551. }
  552. strncpy(dz->wordstor[0],dz->outfilename,k);
  553. strcpy(dz->outfilename,dz->wordstor[0]);
  554. strcat(dz->outfilename,"0");
  555. strcat(dz->outfilename,".wav");
  556. dz->outcnt = 0;
  557. }
  558. (*cmdline)++;
  559. (*cmdlinecnt)--;
  560. return(FINISHED);
  561. }
  562. /************************ OPEN_THE_OUTFILE *********************/
  563. int open_the_outfile(dataptr dz)
  564. {
  565. int exit_status;
  566. if(dz->mode < 2)
  567. dz->infile->channels = dz->mode + 1;
  568. else if(dz->mode == 9)
  569. dz->infile->channels = 2;
  570. else
  571. dz->infile->channels = ALL_CHANS;
  572. dz->outchans = dz->infile->channels;
  573. if((exit_status = create_sized_outfile(dz->outfilename,dz))<0)
  574. return(exit_status);
  575. dz->infile->channels = 1;
  576. return(FINISHED);
  577. }
  578. /***************************** ESTABLISH_APPLICATION **************************/
  579. int establish_application(dataptr dz)
  580. {
  581. aplptr ap;
  582. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  583. sprintf(errstr,"establish_application()\n");
  584. return(MEMORY_ERROR);
  585. }
  586. ap = dz->application;
  587. memset((char *)ap,0,sizeof(struct applic));
  588. return(FINISHED);
  589. }
  590. /************************* INITIALISE_VFLAGS *************************/
  591. int initialise_vflags(dataptr dz)
  592. {
  593. int n;
  594. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  595. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  596. return(MEMORY_ERROR);
  597. }
  598. for(n=0;n<dz->application->vflag_cnt;n++)
  599. dz->vflag[n] = FALSE;
  600. return FINISHED;
  601. }
  602. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  603. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  604. {
  605. int n;
  606. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  607. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  608. return(MEMORY_ERROR);
  609. }
  610. for(n=0;n<tipc;n++)
  611. ap->default_val[n] = 0.0;
  612. return(FINISHED);
  613. }
  614. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  615. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  616. {
  617. int n;
  618. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  619. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  620. return(MEMORY_ERROR);
  621. }
  622. for(n=0;n<tipc;n++)
  623. dz->is_active[n] = (char)0;
  624. return(FINISHED);
  625. }
  626. /************************* SETUP_CRYSTAL_APPLICATION *******************/
  627. int setup_crystal_application(dataptr dz)
  628. {
  629. int exit_status;
  630. aplptr ap;
  631. if((exit_status = establish_application(dz))<0) // GLOBAL
  632. return(FAILED);
  633. ap = dz->application;
  634. // SEE parstruct FOR EXPLANATION of next 2 functions
  635. exit_status = set_param_data(ap,CRYSTALDAT,7,7,"DDDDdDD");
  636. if(exit_status<0)
  637. return(FAILED);
  638. if((exit_status = set_vflgs(ap,"psaPFS",6,"dddddd","",0,0,""))<0)
  639. return(FAILED);
  640. if((exit_status = set_the_legal_internalparam_structure(ap))<0)
  641. return(exit_status); /* LIBRARY */
  642. // set_legal_infile_structure -->
  643. dz->has_otherfile = FALSE;
  644. // assign_process_logic -->
  645. dz->input_data_type = ONE_OR_MANY_SNDFILES;
  646. dz->process_type = UNEQUAL_SNDFILE;
  647. dz->outfiletype = SNDFILE_OUT;
  648. return application_init(dz); //GLOBAL
  649. }
  650. /************************* PARSE_INFILE_AND_CHECK_TYPE *******************/
  651. int parse_infile_and_check_type(char **cmdline,dataptr dz)
  652. {
  653. int exit_status;
  654. infileptr infile_info;
  655. if(!sloom) {
  656. if((infile_info = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  657. sprintf(errstr,"INSUFFICIENT MEMORY for infile structure to test file data.");
  658. return(MEMORY_ERROR);
  659. } else if((exit_status = cdparse(cmdline[0],infile_info))<0) {
  660. sprintf(errstr,"Failed to parse input file %s\n",cmdline[0]);
  661. return(PROGRAM_ERROR);
  662. } else if(infile_info->filetype != SNDFILE) {
  663. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  664. return(DATA_ERROR);
  665. } else if(infile_info->channels != 1) {
  666. sprintf(errstr,"File %s is not of correct type (must be mono)\n",cmdline[0]);
  667. return(DATA_ERROR);
  668. } else if((exit_status = copy_parse_info_to_main_structure(infile_info,dz))<0) {
  669. sprintf(errstr,"Failed to copy file parsing information\n");
  670. return(PROGRAM_ERROR);
  671. }
  672. free(infile_info);
  673. }
  674. return(FINISHED);
  675. }
  676. /************************* SETUP_CRYSTAL_PARAM_RANGES_AND_DEFAULTS *******************/
  677. int setup_crystal_param_ranges_and_defaults(dataptr dz)
  678. {
  679. int exit_status;
  680. aplptr ap = dz->application;
  681. // set_param_ranges()
  682. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  683. // NB total_input_param_cnt is > 0 !!!
  684. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  685. return(FAILED);
  686. // get_param_ranges()
  687. ap->lo[CRY_ROTA] = CRY_ROT_MIN;
  688. ap->hi[CRY_ROTA] = CRY_ROT_MAX;
  689. ap->default_val[CRY_ROTA] = 0.1;
  690. ap->lo[CRY_ROTB] = CRY_ROT_MIN;
  691. ap->hi[CRY_ROTB] = CRY_ROT_MAX;
  692. ap->default_val[CRY_ROTB] = 0.1;
  693. ap->lo[CRY_TWIDTH] = CRY_TW_MIN;
  694. ap->hi[CRY_TWIDTH] = CRY_TW_MAX;
  695. ap->default_val[CRY_TWIDTH] = 1;
  696. ap->lo[CRY_TSTEP] = CRY_TSTEP_MIN;
  697. ap->hi[CRY_TSTEP] = CRY_TSTEP_MAX;
  698. ap->default_val[CRY_TSTEP] = 1;
  699. ap->lo[CRY_DUR] = 0.1;
  700. ap->hi[CRY_DUR] = CRY_DUR_MAX;
  701. ap->default_val[CRY_DUR] = 20;
  702. ap->lo[CRY_PLO] = 0;
  703. ap->hi[CRY_PLO] = 127;
  704. ap->default_val[CRY_PLO] = 36;
  705. ap->lo[CRY_PHI] = 0;
  706. ap->hi[CRY_PHI] = 127;
  707. ap->default_val[CRY_PHI] = 72;
  708. ap->lo[CRY_FPASS] = 16;
  709. ap->hi[CRY_FPASS] = 4000;
  710. ap->default_val[CRY_FPASS] = CRY_PASSBAND;
  711. ap->lo[CRY_FSTOP] = 50;
  712. ap->hi[CRY_FSTOP] = 8000;
  713. ap->default_val[CRY_FSTOP] = CRY_STOPBAND;
  714. ap->lo[CRY_FATT] = -96;
  715. ap->hi[CRY_FATT] = 0;
  716. ap->default_val[CRY_FATT] = CRY_FATT_DFLT;
  717. ap->lo[CRY_FPRESC] = 0;
  718. ap->hi[CRY_FPRESC] = 1;
  719. ap->default_val[CRY_FPRESC] = CRY_FPRESC_DFLT;
  720. ap->lo[CRY_FSLOPE] = 0.1;
  721. ap->hi[CRY_FSLOPE] = 10;
  722. ap->default_val[CRY_FSLOPE] = CRYS_DEPTH_ATTEN;
  723. ap->lo[CRY_SSLOPE] = 0.1;
  724. ap->hi[CRY_SSLOPE] = 10;
  725. ap->default_val[CRY_SSLOPE] = CRYS_PROX_ATTEN;
  726. dz->maxmode = 10;
  727. if(!sloom)
  728. put_default_vals_in_all_params(dz);
  729. return(FINISHED);
  730. }
  731. /********************************* PARSE_SLOOM_DATA *********************************/
  732. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  733. {
  734. int exit_status;
  735. int cnt = 1, infilecnt;
  736. int filesize, insams, inbrksize;
  737. double dummy;
  738. int true_cnt = 0;
  739. // aplptr ap;
  740. while(cnt<=PRE_CMDLINE_DATACNT) {
  741. if(cnt > argc) {
  742. sprintf(errstr,"Insufficient data sent from TK\n");
  743. return(DATA_ERROR);
  744. }
  745. switch(cnt) {
  746. case(1):
  747. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  748. sprintf(errstr,"Cannot read process no. sent from TK\n");
  749. return(DATA_ERROR);
  750. }
  751. break;
  752. case(2):
  753. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  754. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  755. return(DATA_ERROR);
  756. }
  757. if(dz->mode > 0)
  758. dz->mode--;
  759. //setup_particular_application() =
  760. if((exit_status = setup_crystal_application(dz))<0)
  761. return(exit_status);
  762. // ap = dz->application;
  763. break;
  764. case(3):
  765. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  766. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  767. return(DATA_ERROR);
  768. }
  769. if(infilecnt < 1) {
  770. true_cnt = cnt + 1;
  771. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  772. }
  773. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  774. return(exit_status);
  775. break;
  776. case(INPUT_FILETYPE+4):
  777. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  778. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  779. return(DATA_ERROR);
  780. }
  781. break;
  782. case(INPUT_FILESIZE+4):
  783. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  784. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  785. return(DATA_ERROR);
  786. }
  787. dz->insams[0] = filesize;
  788. break;
  789. case(INPUT_INSAMS+4):
  790. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  791. sprintf(errstr,"Cannot read insams sent from TK\n");
  792. return(DATA_ERROR);
  793. }
  794. dz->insams[0] = insams;
  795. break;
  796. case(INPUT_SRATE+4):
  797. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  798. sprintf(errstr,"Cannot read srate sent from TK\n");
  799. return(DATA_ERROR);
  800. }
  801. break;
  802. case(INPUT_CHANNELS+4):
  803. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  804. sprintf(errstr,"Cannot read channels sent from TK\n");
  805. return(DATA_ERROR);
  806. }
  807. break;
  808. case(INPUT_STYPE+4):
  809. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  810. sprintf(errstr,"Cannot read stype sent from TK\n");
  811. return(DATA_ERROR);
  812. }
  813. break;
  814. case(INPUT_ORIGSTYPE+4):
  815. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  816. sprintf(errstr,"Cannot read origstype sent from TK\n");
  817. return(DATA_ERROR);
  818. }
  819. break;
  820. case(INPUT_ORIGRATE+4):
  821. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  822. sprintf(errstr,"Cannot read origrate sent from TK\n");
  823. return(DATA_ERROR);
  824. }
  825. break;
  826. case(INPUT_MLEN+4):
  827. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  828. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  829. return(DATA_ERROR);
  830. }
  831. break;
  832. case(INPUT_DFAC+4):
  833. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  834. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  835. return(DATA_ERROR);
  836. }
  837. break;
  838. case(INPUT_ORIGCHANS+4):
  839. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  840. sprintf(errstr,"Cannot read origchans sent from TK\n");
  841. return(DATA_ERROR);
  842. }
  843. break;
  844. case(INPUT_SPECENVCNT+4):
  845. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  846. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  847. return(DATA_ERROR);
  848. }
  849. dz->specenvcnt = dz->infile->specenvcnt;
  850. break;
  851. case(INPUT_WANTED+4):
  852. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  853. sprintf(errstr,"Cannot read wanted sent from TK\n");
  854. return(DATA_ERROR);
  855. }
  856. break;
  857. case(INPUT_WLENGTH+4):
  858. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  859. sprintf(errstr,"Cannot read wlength sent from TK\n");
  860. return(DATA_ERROR);
  861. }
  862. break;
  863. case(INPUT_OUT_CHANS+4):
  864. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  865. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  866. return(DATA_ERROR);
  867. }
  868. break;
  869. /* RWD these chanegs to samps - tk will have to deal with that! */
  870. case(INPUT_DESCRIPTOR_BYTES+4):
  871. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  872. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  873. return(DATA_ERROR);
  874. }
  875. break;
  876. case(INPUT_IS_TRANSPOS+4):
  877. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  878. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  879. return(DATA_ERROR);
  880. }
  881. break;
  882. case(INPUT_COULD_BE_TRANSPOS+4):
  883. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  884. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  885. return(DATA_ERROR);
  886. }
  887. break;
  888. case(INPUT_COULD_BE_PITCH+4):
  889. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  890. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  891. return(DATA_ERROR);
  892. }
  893. break;
  894. case(INPUT_DIFFERENT_SRATES+4):
  895. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  896. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  897. return(DATA_ERROR);
  898. }
  899. break;
  900. case(INPUT_DUPLICATE_SNDS+4):
  901. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  902. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  903. return(DATA_ERROR);
  904. }
  905. break;
  906. case(INPUT_BRKSIZE+4):
  907. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  908. sprintf(errstr,"Cannot read brksize sent from TK\n");
  909. return(DATA_ERROR);
  910. }
  911. if(inbrksize > 0) {
  912. switch(dz->input_data_type) {
  913. case(WORDLIST_ONLY):
  914. break;
  915. case(PITCH_AND_PITCH):
  916. case(PITCH_AND_TRANSPOS):
  917. case(TRANSPOS_AND_TRANSPOS):
  918. dz->tempsize = inbrksize;
  919. break;
  920. case(BRKFILES_ONLY):
  921. case(UNRANGED_BRKFILE_ONLY):
  922. case(DB_BRKFILES_ONLY):
  923. case(ALL_FILES):
  924. case(ANY_NUMBER_OF_ANY_FILES):
  925. if(dz->extrabrkno < 0) {
  926. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  927. return(DATA_ERROR);
  928. }
  929. if(dz->brksize == NULL) {
  930. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  931. return(PROGRAM_ERROR);
  932. }
  933. dz->brksize[dz->extrabrkno] = inbrksize;
  934. break;
  935. default:
  936. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  937. dz->input_data_type);
  938. return(PROGRAM_ERROR);
  939. }
  940. break;
  941. }
  942. break;
  943. case(INPUT_NUMSIZE+4):
  944. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  945. sprintf(errstr,"Cannot read numsize sent from TK\n");
  946. return(DATA_ERROR);
  947. }
  948. break;
  949. case(INPUT_LINECNT+4):
  950. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  951. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  952. return(DATA_ERROR);
  953. }
  954. break;
  955. case(INPUT_ALL_WORDS+4):
  956. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  957. sprintf(errstr,"Cannot read all_words sent from TK\n");
  958. return(DATA_ERROR);
  959. }
  960. break;
  961. case(INPUT_ARATE+4):
  962. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  963. sprintf(errstr,"Cannot read arate sent from TK\n");
  964. return(DATA_ERROR);
  965. }
  966. break;
  967. case(INPUT_FRAMETIME+4):
  968. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  969. sprintf(errstr,"Cannot read frametime sent from TK\n");
  970. return(DATA_ERROR);
  971. }
  972. dz->frametime = (float)dummy;
  973. break;
  974. case(INPUT_WINDOW_SIZE+4):
  975. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  976. sprintf(errstr,"Cannot read window_size sent from TK\n");
  977. return(DATA_ERROR);
  978. }
  979. break;
  980. case(INPUT_NYQUIST+4):
  981. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  982. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  983. return(DATA_ERROR);
  984. }
  985. break;
  986. case(INPUT_DURATION+4):
  987. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  988. sprintf(errstr,"Cannot read duration sent from TK\n");
  989. return(DATA_ERROR);
  990. }
  991. break;
  992. case(INPUT_MINBRK+4):
  993. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  994. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  995. return(DATA_ERROR);
  996. }
  997. break;
  998. case(INPUT_MAXBRK+4):
  999. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  1000. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  1001. return(DATA_ERROR);
  1002. }
  1003. break;
  1004. case(INPUT_MINNUM+4):
  1005. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  1006. sprintf(errstr,"Cannot read minnum sent from TK\n");
  1007. return(DATA_ERROR);
  1008. }
  1009. break;
  1010. case(INPUT_MAXNUM+4):
  1011. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  1012. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  1013. return(DATA_ERROR);
  1014. }
  1015. break;
  1016. default:
  1017. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  1018. return(PROGRAM_ERROR);
  1019. }
  1020. cnt++;
  1021. }
  1022. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  1023. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  1024. return(DATA_ERROR);
  1025. }
  1026. if(true_cnt)
  1027. cnt = true_cnt;
  1028. *cmdlinecnt = 0;
  1029. while(cnt < argc) {
  1030. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  1031. return(exit_status);
  1032. cnt++;
  1033. }
  1034. return(FINISHED);
  1035. }
  1036. /********************************* GET_TK_CMDLINE_WORD *********************************/
  1037. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  1038. {
  1039. if(*cmdlinecnt==0) {
  1040. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  1041. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  1042. return(MEMORY_ERROR);
  1043. }
  1044. } else {
  1045. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  1046. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  1047. return(MEMORY_ERROR);
  1048. }
  1049. }
  1050. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  1051. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  1052. return(MEMORY_ERROR);
  1053. }
  1054. strcpy((*cmdline)[*cmdlinecnt],q);
  1055. (*cmdlinecnt)++;
  1056. return(FINISHED);
  1057. }
  1058. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  1059. int assign_file_data_storage(int infilecnt,dataptr dz)
  1060. {
  1061. int exit_status;
  1062. int no_sndfile_system_files = FALSE;
  1063. dz->infilecnt = infilecnt;
  1064. if((exit_status = allocate_filespace(dz))<0)
  1065. return(exit_status);
  1066. if(no_sndfile_system_files)
  1067. dz->infilecnt = 0;
  1068. return(FINISHED);
  1069. }
  1070. /****************************** SET_THE_LEGAL_INTERNALPARAM_STRUCTURE *********************************/
  1071. int set_the_legal_internalparam_structure(aplptr ap)
  1072. {
  1073. int exit_status;
  1074. if((exit_status = set_internalparam_data("id",ap))<0)
  1075. return exit_status;
  1076. return FINISHED;
  1077. }
  1078. /************************* redundant functions: to ensure libs compile OK *******************/
  1079. int assign_process_logic(dataptr dz)
  1080. {
  1081. return(FINISHED);
  1082. }
  1083. void set_legal_infile_structure(dataptr dz)
  1084. {}
  1085. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  1086. {
  1087. return(FINISHED);
  1088. }
  1089. int setup_internal_arrays_and_array_pointers(dataptr dz)
  1090. {
  1091. return(FINISHED);
  1092. }
  1093. int establish_bufptrs_and_extra_buffers(dataptr dz)
  1094. {
  1095. return(FINISHED);
  1096. }
  1097. int read_special_data(char *str,dataptr dz)
  1098. {
  1099. return(FINISHED);
  1100. }
  1101. int inner_loop
  1102. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  1103. {
  1104. return(FINISHED);
  1105. }
  1106. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1107. {
  1108. return(FINISHED);
  1109. }
  1110. /******************************** USAGE1 ********************************/
  1111. int usage1(void)
  1112. {
  1113. usage2("rotate");
  1114. return(USAGE_ONLY);
  1115. }
  1116. /**************************** CHECK_CRYSTAL_PARAM_VALIDITY_AND_CONSISTENCY *****************************/
  1117. int check_crystal_param_validity_and_consistency(dataptr dz)
  1118. {
  1119. double temp;
  1120. if(!dz->brksize[CRY_PLO] && !dz->brksize[CRY_PHI]) {
  1121. if(flteq(dz->param[CRY_PLO],dz->param[CRY_PHI])) {
  1122. sprintf(errstr,"Zero pitchrange (%lf to %lf) specified.\n",dz->param[CRY_PLO],dz->param[CRY_PHI]);
  1123. return(DATA_ERROR);
  1124. } else if(dz->param[CRY_PLO] > dz->param[CRY_PHI]) {
  1125. fprintf(stdout,"WARNING: Inverted pitchrange (%lf to %lf) specified.\n",dz->param[CRY_PLO],dz->param[CRY_PHI]);
  1126. fflush(stdout);
  1127. }
  1128. }
  1129. if(dz->brksize[CRY_TSTEP])
  1130. dz->param[CRY_TSTEP] = dz->brk[CRY_TSTEP][1];
  1131. if(dz->param[CRY_DUR] < dz->param[CRY_TSTEP]) {
  1132. sprintf(errstr,"Output duration (%lf) less than timestep (%lf) from 1st event to next.\n",dz->param[CRY_DUR],dz->param[CRY_TSTEP]);
  1133. return(DATA_ERROR);
  1134. }
  1135. if(dz->brksize[CRY_TWIDTH])
  1136. dz->param[CRY_TWIDTH] = dz->brk[CRY_TWIDTH][1];
  1137. if(dz->param[CRY_DUR] < dz->param[CRY_TWIDTH]) {
  1138. sprintf(errstr,"Output duration (%lf) less than timewidth of first event (%lf).\n",dz->param[CRY_DUR],dz->param[CRY_TWIDTH]);
  1139. return(DATA_ERROR);
  1140. }
  1141. if(dz->param[CRY_FPASS] > dz->param[CRY_FSTOP]) {
  1142. temp = dz->param[CRY_FPASS];
  1143. dz->param[CRY_FPASS] = dz->param[CRY_FSTOP];
  1144. dz->param[CRY_FSTOP] = temp;
  1145. }
  1146. if((temp = dz->param[CRY_FSTOP] - dz->param[CRY_FPASS]) < CRY_MINFBWIDTH) {
  1147. sprintf(errstr,"Frequency difference between filter pass and stop bands (%lf) too small (min %lf Hz).\n",temp,CRY_MINFBWIDTH);
  1148. return(DATA_ERROR);
  1149. }
  1150. return FINISHED;
  1151. }
  1152. /********************************************************************************************/
  1153. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1154. {
  1155. if(!strcmp(prog_identifier_from_cmdline,"rotate")) dz->process = CRYSTAL;
  1156. else {
  1157. sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  1158. return(USAGE_ONLY);
  1159. }
  1160. return(FINISHED);
  1161. }
  1162. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  1163. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  1164. {
  1165. int n;
  1166. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1167. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  1168. return(MEMORY_ERROR);
  1169. }
  1170. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1171. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  1172. return(MEMORY_ERROR);
  1173. }
  1174. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1175. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  1176. return(MEMORY_ERROR);
  1177. }
  1178. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1179. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  1180. return(MEMORY_ERROR);
  1181. }
  1182. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1183. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  1184. return(MEMORY_ERROR);
  1185. }
  1186. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1187. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  1188. return(MEMORY_ERROR);
  1189. }
  1190. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1191. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  1192. return(MEMORY_ERROR);
  1193. }
  1194. for(n=0;n<brkcnt;n++) {
  1195. dz->brk[n] = NULL;
  1196. dz->brkptr[n] = NULL;
  1197. dz->brkinit[n] = 0;
  1198. dz->brksize[n] = 0;
  1199. }
  1200. return(FINISHED);
  1201. }
  1202. /******************************** USAGE2 ********************************/
  1203. int usage2(char *str)
  1204. {
  1205. if(!strcmp(str,"rotate")) {
  1206. fprintf(stderr,
  1207. "crystal rotate 1-10 fi [fi2 fi3..] fo vdat rota rotb twidth tstep dur plo phi\n"
  1208. " [-ppass -sstop] [-afatt] [-Pfpresc] [-Ffslope] [-Ssslope]\n"
  1209. "\n"
  1210. "Generate N snd-events based on position of N vertices of a crystal,\n"
  1211. "Then rotate crystal in 3-d space, and generate another group of N events, etc.\n"
  1212. "X coord -> time &, if stereo, space-position; Y -> pitch; Z -> brightness..i.e.\n"
  1213. "Z-far snds lopass-filtrd mixed to orig; Z-close snds, 8va up, stacked on orig.\n"
  1214. "\n"
  1215. "FI One Mono infile, multiply-read (with delay), generating out-events.\n"
  1216. " OR N mono infiles, generating different events for N vertices.\n"
  1217. "FO Output file.\n"
  1218. "VDAT Data file contains\n"
  1219. " (1) Triples, being (initial) X,Y,Z, coords of CRYSTAL VERTICES.\n"
  1220. " Range > -1 to <1. Xsquared + Ysqrd + Zsqrd < 1 for all vertices.\n"
  1221. " (2) Time-val pairs defining envelope imposed on sound events.\n"
  1222. " Times start at 0 & increase. Final time = duration of events.\n"
  1223. " Value range 0 to 1. First and last values must be zero.\n"
  1224. "ROTA,ROTB Rotate speed in xy_plane, & xz_plane, revs per sec (Range %.2lf to %.2lf)\n"
  1225. "TWIDTH Max time between onsets of 1st and last event in any N-events group.\n"
  1226. "TSTEP Time-step between each sampling of all N vertices of rotating-crystal.\n"
  1227. "DUR Total duration of output (must be greater than TSTEP and TWIDTH).\n"
  1228. "PLO,PHI Minimum and Maximum (MIDI) pitch of any event.\n"
  1229. "PASS,STOP Pass+stop bands (Hz) for lopass filter.(stopfrq - passfrq >= %.0lf Hz).\n"
  1230. "FATT Max attenuation produced by filter-stop (dB) Range 0 to -96.\n"
  1231. "FPRESC Gain applied to attenuate source before applying filter (0-1).\n"
  1232. "FSLOPE Slope curve mixing filtered to unfilt snd (depth). (Range %.2lf to %.2lf).\n"
  1233. "SSLOPE Slope curve mixing transposed snd to orig (close). (Range %.2lf to %.2lf).\n"
  1234. " In both cases Linear slope = 1.0\n"
  1235. "FOG Generic name for output files.\n"
  1236. "OUTCNT Number of rotated-sets to output.\n"
  1237. "MODES\n"
  1238. "1 Mono output\n"
  1239. "2 Stereo output\n"
  1240. "3 Two chans of 8-chan output, spaced by single channel (here, chans 1 & 3).\n"
  1241. "4,5,6 Ditto, chan-pair steps clockwise,anticlock or randomly btwn groups-of-events.\n"
  1242. "7,8,9 Ditto, but pair of chans adjacent (e.g. 1,2 or 5,6).\n"
  1243. "10 Stereo output: each set-of-vertices output as a separate soundfile.\n",
  1244. CRY_ROT_MIN,CRY_ROT_MAX,CRY_MINFBWIDTH,MIN_FSLOPE,MAX_FSLOPE,MIN_SSLOPE,MAX_SSLOPE);
  1245. } else
  1246. fprintf(stdout,"Unknown option '%s'\n",str);
  1247. return(USAGE_ONLY);
  1248. }
  1249. int usage3(char *str1,char *str2)
  1250. {
  1251. fprintf(stderr,"Insufficient parameters on command line.\n");
  1252. return(USAGE_ONLY);
  1253. }
  1254. /****************************** GET_MODE *********************************/
  1255. int get_the_mode_from_cmdline(char *str,dataptr dz)
  1256. {
  1257. char temp[200], *p;
  1258. if(sscanf(str,"%s",temp)!=1) {
  1259. sprintf(errstr,"Cannot read mode of program.\n");
  1260. return(USAGE_ONLY);
  1261. }
  1262. p = temp + strlen(temp) - 1;
  1263. while(p >= temp) {
  1264. if(!isdigit(*p)) {
  1265. fprintf(stderr,"Invalid mode of program entered.\n");
  1266. return(USAGE_ONLY);
  1267. }
  1268. p--;
  1269. }
  1270. if(sscanf(str,"%d",&dz->mode)!=1) {
  1271. fprintf(stderr,"Cannot read mode of program.\n");
  1272. return(USAGE_ONLY);
  1273. }
  1274. if(dz->mode <= 0 || dz->mode > dz->maxmode) {
  1275. fprintf(stderr,"Program mode value [%d] is out of range [1 - %d].\n",dz->mode,dz->maxmode);
  1276. return(USAGE_ONLY);
  1277. }
  1278. dz->mode--; /* CHANGE TO INTERNAL REPRESENTATION OF MODE NO */
  1279. return(FINISHED);
  1280. }
  1281. /**************************** HANDLE_THE_SPECIAL_DATA ****************************
  1282. *
  1283. * Series of lines containing x,y,z coords of crystal vertices.
  1284. * ... followed by envelope data for creating sound from infile.
  1285. */
  1286. int handle_the_special_data(char *str,dataptr dz)
  1287. {
  1288. FILE *fp;
  1289. double dummy = -1.0, /*sum,*/ vectorlen, lasttime, x, y, z;
  1290. char temp[200], *p;
  1291. int cnt = 0, linecnt = 0, vertexcnt = 0, datacnt = 0, jj, envelcnt = 0, k;
  1292. int istime, inenvel = 0;
  1293. if((fp = fopen(str,"r"))==NULL) {
  1294. sprintf(errstr,"Cannot open file %s to read envelope data.\n",str);
  1295. return(DATA_ERROR);
  1296. }
  1297. while(fgets(temp,200,fp)!=NULL) {
  1298. cnt = 0;
  1299. p = temp;
  1300. while(isspace(*p))
  1301. p++;
  1302. if(*p == ';' || *p == ENDOFSTR) // Allow comments in file
  1303. continue;
  1304. while(get_float_from_within_string(&p,&dummy))
  1305. cnt++;
  1306. if(inenvel)
  1307. envelcnt += cnt;
  1308. else {
  1309. if(cnt != 3) {
  1310. if(vertexcnt == 0) { // Must read all vertex-triples before reading envelope
  1311. sprintf(errstr,"Data in line %d not valid triples (x:y:z coords) in file %s\n",linecnt+1,str);
  1312. return(DATA_ERROR);
  1313. } else { // Once all triples read, before counting envelope data, note size of triples-data
  1314. inenvel = 1;
  1315. envelcnt += cnt;
  1316. }
  1317. } else {
  1318. vertexcnt++;
  1319. }
  1320. }
  1321. linecnt++;
  1322. }
  1323. if(linecnt == 0) {
  1324. sprintf(errstr,"No data found in file %s\n",str);
  1325. return(DATA_ERROR);
  1326. }
  1327. if(vertexcnt == 0) {
  1328. sprintf(errstr,"No crystal vertex data found in file %s\n",str);
  1329. return(DATA_ERROR);
  1330. }
  1331. datacnt = vertexcnt * 3;
  1332. if(envelcnt == 0) {
  1333. sprintf(errstr,"No envelope data found in file %s\n",str);
  1334. return(DATA_ERROR);
  1335. }
  1336. if(ODD(envelcnt)) {
  1337. sprintf(errstr,"envelope data not paired corectly in file %s\n",str);
  1338. return(DATA_ERROR);
  1339. }
  1340. if(dz->infilecnt > 1 && vertexcnt != dz->infilecnt) {
  1341. sprintf(errstr,"Number of input files (%d) does not correspond with number of vertices (%d)\n",dz->infilecnt,vertexcnt);
  1342. return DATA_ERROR;
  1343. }
  1344. istime = 1;
  1345. fseek(fp,0,0);
  1346. linecnt = 0;
  1347. cnt = 0;
  1348. lasttime = -1.0;
  1349. while(fgets(temp,200,fp)!=NULL) {
  1350. p = temp;
  1351. while(isspace(*p))
  1352. p++;
  1353. if(*p == ';' || *p == ENDOFSTR) // Allow comments in file
  1354. continue;
  1355. while(get_float_from_within_string(&p,&dummy)) {
  1356. if(cnt < datacnt) {
  1357. k = cnt % 3;
  1358. if(dummy > 1.0 || dummy < -1.0) {
  1359. switch(k) {
  1360. case(0):
  1361. sprintf(errstr,"Crystal X-coord (%lf) out of range (-1 to 1) in line %d file %s\n",dummy,linecnt+1,str);
  1362. break;
  1363. case(1):
  1364. sprintf(errstr,"Crystal Y-coord (%lf) out of range (-1 to 1) in line %d file %s\n",dummy,linecnt+1,str);
  1365. break;
  1366. case(2):
  1367. sprintf(errstr,"Crystal Z-coord (%lf) out of range (-1 to 1) in line %d file %s\n",dummy,linecnt+1,str);
  1368. break;
  1369. }
  1370. return(DATA_ERROR);
  1371. }
  1372. } else {
  1373. if(istime) {
  1374. if(lasttime < 0.0) {
  1375. if(dummy != 0.0) {
  1376. sprintf(errstr,"First time in envelope data (%lf) not at zero in line %d file %s\n",dummy,linecnt+1,str);
  1377. return(DATA_ERROR);
  1378. }
  1379. } else if(dummy <= lasttime) {
  1380. sprintf(errstr,"Times do not advance in envelope data at time (%lf) in line %d file %s\n",dummy,linecnt+1,str);
  1381. return(DATA_ERROR);
  1382. }
  1383. lasttime = dummy;
  1384. } else {
  1385. if(lasttime == 0.0) { // Envelope values must start at zero
  1386. if(dummy != 0.0) {
  1387. sprintf(errstr,"First envelope value (%lf) is not zero in line %d file %s\n",dummy,linecnt+1,str);
  1388. return(DATA_ERROR);
  1389. }
  1390. } else if(dummy < 0.0 || dummy > 1.0) {
  1391. sprintf(errstr,"Envelope value (%lf) out of range (0 to 1) in line %d file %s\n",dummy,linecnt+1,str);
  1392. return(DATA_ERROR);
  1393. }
  1394. }
  1395. istime = !istime;
  1396. }
  1397. cnt++;
  1398. }
  1399. linecnt++;
  1400. }
  1401. if(dummy != 0.0) {
  1402. sprintf(errstr,"Last envelope value (%lf) is not zero in line %d file %s\n",dummy,linecnt,str);
  1403. return(DATA_ERROR);
  1404. }
  1405. if((dz->parray = (double **)malloc(10 * sizeof(double *)))==NULL) {
  1406. sprintf(errstr,"INSUFFICIENT MEMORY to store crystal special data.\n");
  1407. return(MEMORY_ERROR);
  1408. }
  1409. if((dz->parray[ORIG_VTX_DATA] = (double *)malloc(datacnt * sizeof(double)))==NULL) { // Stores initial coords of cristal vertices
  1410. sprintf(errstr,"INSUFFICIENT MEMORY to store crystal vertex coords data.\n");
  1411. return(MEMORY_ERROR);
  1412. }
  1413. if((dz->parray[VERTEX_DATA] = (double *)malloc(datacnt * sizeof(double)))==NULL) { // Stores coords of cristal vertices as they rotate
  1414. sprintf(errstr,"INSUFFICIENT MEMORY to store crystal vector data.\n");
  1415. return(MEMORY_ERROR);
  1416. }
  1417. if((dz->parray[ENV_DATA] = (double *)malloc(envelcnt * sizeof(double)))==NULL) { // Stores sound-events-envelope
  1418. sprintf(errstr,"INSUFFICIENT MEMORY to store envelope data.\n");
  1419. return(MEMORY_ERROR);
  1420. }
  1421. dz->no_of_vertices = vertexcnt;
  1422. dz->envdatalen = envelcnt;
  1423. cnt = 0;
  1424. fseek(fp,0,0);
  1425. while(fgets(temp,200,fp)!=NULL) {
  1426. p = temp;
  1427. while(isspace(*p))
  1428. p++;
  1429. if(*p == ';' || *p == ENDOFSTR) // Allow comments in file
  1430. continue;
  1431. while(get_float_from_within_string(&p,&dummy)) {
  1432. if(cnt < datacnt)
  1433. dz->parray[ORIG_VTX_DATA][cnt] = dummy; // Store initial coords of crystal vertices
  1434. else
  1435. dz->parray[ENV_DATA][cnt - datacnt] = dummy; // Store sound-envelope data
  1436. cnt++;
  1437. }
  1438. }
  1439. fclose(fp);
  1440. for(vertexcnt = 0; vertexcnt < dz->no_of_vertices; vertexcnt++) {
  1441. jj = vertexcnt * 3;
  1442. // sum = 0.0;
  1443. x = dz->parray[ORIG_VTX_DATA][jj];
  1444. y = dz->parray[ORIG_VTX_DATA][jj+1];
  1445. z = dz->parray[ORIG_VTX_DATA][jj+2];
  1446. if((get_vectorlen(&vectorlen,x,y,z))<0) {
  1447. sprintf(errstr,"vertex %d lies outside the unit sphere.\n",vertexcnt+1);
  1448. return DATA_ERROR;
  1449. }
  1450. }
  1451. dz->rampbrksize = (int)ceil(lasttime * dz->infile->srate); // Remember duration of envelope, in samples
  1452. return FINISHED;
  1453. }
  1454. /**************************** CRYSTAL_ROTATE ****************************/
  1455. int crystal_rotate(dataptr dz)
  1456. {
  1457. int passno, warning = 0, *perm, permno, exit_status, eightrot, vertexno;
  1458. int vertexbas, vertindex, monosamptime, i;
  1459. int maxwrite = 0, grpcnt, minsamptime;
  1460. double *vertexcoord = dz->parray[VERTEX_DATA], rotation_in_xy_plane, rotation_in_xz_plane, midipitch, normaliser = 1.0;
  1461. double *vertexorig = dz->parray[ORIG_VTX_DATA];
  1462. double eventtime, outdur = dz->param[CRY_DUR], x, y, z, depth, closeness, maxlevel = 0.0;
  1463. float *obuf = dz->sampbuf[THISOBUF];
  1464. dz->tempsize = (int)ceil(outdur * (double)dz->infile->srate) * dz->outchans;
  1465. if((perm = (int *)malloc(ALL_CHANS * sizeof(int))) == NULL) {
  1466. sprintf(errstr,"INSUFFICIENT MEMORY to create perm buffer.\n");
  1467. return(PROGRAM_ERROR);
  1468. }
  1469. doperm(perm,ALL_CHANS);
  1470. permno = 0;
  1471. if(dz->mode == 5 || dz->mode == 8) // Random orientations in 8-channel space
  1472. eightrot = perm[permno];
  1473. else
  1474. eightrot = 0; // modes 3,4,6,7: rotating orientations in 8-channel space
  1475. if((exit_status = setup_lphp_filter(dz))<0)
  1476. return exit_status;
  1477. for(passno = 0; passno < 2; passno++) {
  1478. if(passno == 0)
  1479. fprintf(stdout,"INFO: 1st pass : checking levels.\n");
  1480. else
  1481. fprintf(stdout,"INFO: 2nd pass : generating output.\n");
  1482. fflush(stdout);
  1483. rotation_in_xy_plane = 0.0; // INITIALISE ROTATIONS
  1484. rotation_in_xz_plane = 0.0;
  1485. for(vertexno=0;vertexno<dz->no_of_vertices;vertexno++) { // INITIALISE VERTEX-COORDS
  1486. vertexbas = vertexno * 3;
  1487. vertindex = vertexbas;
  1488. vertexcoord[vertindex] = vertexorig[vertindex];
  1489. vertindex++;
  1490. vertexcoord[vertindex] = vertexorig[vertindex];
  1491. vertindex++;
  1492. vertexcoord[vertindex] = vertexorig[vertindex];
  1493. }
  1494. if(passno > 0)
  1495. sndseekEx(dz->ifd[0],0,0);
  1496. maxwrite = 0;
  1497. dz->total_samps_written = 0;
  1498. memset((char *)obuf,0,dz->buflen * 2 * sizeof(float)); // Zero outbuffer and overflow buffer
  1499. memcpy((char *)dz->parray[VERTEX_DATA],(char *)dz->parray[ORIG_VTX_DATA],(dz->no_of_vertices * 3 * sizeof(double)));
  1500. eventtime = 0.0;
  1501. while(eventtime < outdur) {
  1502. if((exit_status = read_values_from_all_existing_brktables(eventtime,dz))<0)
  1503. return DATA_ERROR;
  1504. rotation_in_xy_plane += dz->param[CRY_ROTA] * dz->param[CRY_TSTEP] * TWOPI; // rotation is TOTAL rotation from original position
  1505. while(rotation_in_xy_plane >= TWOPI)
  1506. rotation_in_xy_plane -= TWOPI;
  1507. while(rotation_in_xy_plane < -TWOPI)
  1508. rotation_in_xy_plane += TWOPI;
  1509. if(flteq(0.0,rotation_in_xy_plane)) // try to avoid rounding errors
  1510. rotation_in_xy_plane = 0.0;
  1511. if(flteq(TWOPI,rotation_in_xy_plane)) // try to avoid rounding errors
  1512. rotation_in_xy_plane = TWOPI;
  1513. rotation_in_xz_plane += dz->param[CRY_ROTB] * dz->param[CRY_TSTEP] * TWOPI; // rotation is TOTAL rotation from original position
  1514. while(rotation_in_xz_plane >= TWOPI)
  1515. rotation_in_xz_plane -= TWOPI;
  1516. while(rotation_in_xz_plane < -TWOPI)
  1517. rotation_in_xz_plane += TWOPI;
  1518. if(flteq(0.0,rotation_in_xz_plane)) // try to avoid rounding errors
  1519. rotation_in_xz_plane = 0.0;
  1520. if(flteq(TWOPI,rotation_in_xz_plane)) // try to avoid rounding errors
  1521. rotation_in_xz_plane = TWOPI;
  1522. minsamptime = (int)(MAXINT - 1);
  1523. for(vertexno=0;vertexno<dz->no_of_vertices;vertexno++) {
  1524. vertexbas = vertexno * 3;
  1525. x = vertexcoord[vertexbas];
  1526. if((exit_status = calculate_time_params(&monosamptime,x,eventtime,dz))<0) // Calculate time of earliest event in group
  1527. return exit_status;
  1528. minsamptime = min(minsamptime,monosamptime);
  1529. }
  1530. if(dz->mode == 9)
  1531. maxwrite = 0; // In mode 10, check how long vertex-set is, in each separate case, in order to write to its unique outfile
  1532. else {
  1533. if((exit_status = check_position_of_event_group_in_output_buf(passno,&maxlevel,&maxwrite,minsamptime,normaliser,dz))<0)
  1534. return exit_status; // In all other cases, check if outbuf is full, and if so, write to the (single) outfile
  1535. }
  1536. for(vertexno=0;vertexno<dz->no_of_vertices;vertexno++) {
  1537. vertexbas = vertexno * 3;
  1538. vertindex = vertexbas;
  1539. x = vertexcoord[vertindex++]; // NB vertexcoords have been initialised (above loop) to ORIGINAL COORDS
  1540. y = vertexcoord[vertindex++];
  1541. z = vertexcoord[vertindex];
  1542. if((exit_status = calculate_pitch_and_time_params(&midipitch,&monosamptime,x,y,eventtime,dz))<0)
  1543. return exit_status;
  1544. if((exit_status = delay_transpose_input_sound(midipitch,vertexno,dz))<0) // Transpose snd -> TRNSBUF : NORM
  1545. return exit_status;
  1546. depth = z;
  1547. if(depth < 0) { // Distant sounds are filtered
  1548. if((exit_status = filter_sound(depth,dz))<0) // Filter sound --> FSBUF--> mix with orig --> TRNSBUF
  1549. return exit_status;
  1550. if((exit_status = envelope_sound(1,dz))<0) // TRNSBUF --> ENVBUF : NORM
  1551. return exit_status;
  1552. } else {
  1553. if((exit_status = envelope_sound(0,dz))<0) // TRNSBUF --> ENVBUF
  1554. return exit_status;
  1555. if(depth > 0) { // Close sounds are stacked
  1556. closeness = depth;
  1557. if((exit_status = stack_enveld_snd(closeness,dz)) < 0) // Transpose sound by 8va, --> FSBUF (suitably time-offset)
  1558. return PROGRAM_ERROR; // and by 2 8vas --> TRANSBUF (suitably time-offset)
  1559. } // Then mix the orig and 2 transpositions --> ENVBUF : NORM
  1560. }
  1561. if((exit_status = write_sound_into_output_buf(monosamptime,minsamptime,x,eightrot,&maxwrite,dz))<0)
  1562. return exit_status;
  1563. // AFTER using existing coords of vertices ... rotate the crystal
  1564. vertindex = vertexbas;
  1565. x = vertexorig[vertindex++]; // Get original vertex coords
  1566. y = vertexorig[vertindex++];
  1567. z = vertexorig[vertindex]; // Apply TOTAL rotation to this data
  1568. rotate_vertex(&x,&y,&z,rotation_in_xy_plane,rotation_in_xz_plane,vertexno,eventtime,&warning); // Do vector <= 1 test
  1569. vertindex = vertexbas;
  1570. vertexcoord[vertindex++] = x; // Reset vertex coords for next pass
  1571. vertexcoord[vertindex++] = y;
  1572. vertexcoord[vertindex] = z;
  1573. }
  1574. switch(dz->mode) {
  1575. case(3): // STEPPING CLOCKWISE
  1576. case(6):
  1577. if(++eightrot >= ALL_CHANS) // Rotate (next) sound clockwise
  1578. eightrot -= ALL_CHANS;
  1579. break;
  1580. case(4): // STEPPING antiCLOCKWISE
  1581. case(7):
  1582. if(--eightrot < 0) // Rotate (next) sound anticlockwise
  1583. eightrot += ALL_CHANS;
  1584. break;
  1585. case(5): // STEPPING RANDOMLY // Random orientation
  1586. case(8):
  1587. if(++permno >= ALL_CHANS) {
  1588. doperm(perm,ALL_CHANS);
  1589. permno = 0;
  1590. }
  1591. eightrot = perm[permno];
  1592. break;
  1593. case(9):
  1594. if(passno == 0) {
  1595. dz->total_samps_written += maxwrite;
  1596. dz->process = GREV;
  1597. display_virtual_time(0,dz);
  1598. dz->process = CRYSTAL;
  1599. for(i=0;i < maxwrite;i++)
  1600. maxlevel = max(maxlevel,fabs(obuf[i]));
  1601. } else {
  1602. for(i=0;i < maxwrite;i++)
  1603. obuf[i] = (float)(obuf[i] * normaliser);
  1604. if((exit_status = write_rotated_crystal_sound(obuf,maxwrite,dz))<0)
  1605. return exit_status;
  1606. }
  1607. maxwrite = 0;
  1608. break;
  1609. }
  1610. eventtime += dz->param[CRY_TSTEP];
  1611. }
  1612. if(dz->mode == 9) {
  1613. if(passno == 0) {
  1614. if(maxlevel > MAXCRYSLEVEL)
  1615. normaliser = MAXCRYSLEVEL/maxlevel;
  1616. }
  1617. } else {
  1618. if(passno == 0) {
  1619. if(maxwrite > 0) {
  1620. dz->total_samps_written += maxwrite;
  1621. dz->process = GREV;
  1622. display_virtual_time(0,dz);
  1623. dz->process = CRYSTAL;
  1624. for(i=0;i < maxwrite;i++)
  1625. maxlevel = max(maxlevel,fabs(obuf[i]));
  1626. }
  1627. if(maxlevel > MAXCRYSLEVEL) // Set normaliser, even if no samps still to write
  1628. normaliser = MAXCRYSLEVEL/maxlevel;
  1629. } else if(maxwrite > 0) {
  1630. if(normaliser != 1.0) {
  1631. for(i=0;i < maxwrite;i++) // normalise output data
  1632. obuf[i] = (float)(obuf[i] * normaliser);
  1633. }
  1634. if(dz->outchans > 1) {
  1635. if(maxwrite % dz->outchans != 0) { // Ensure a whole final channel group is written
  1636. grpcnt = maxwrite/dz->outchans;
  1637. grpcnt++;
  1638. maxwrite = grpcnt * dz->outchans;
  1639. }
  1640. } // write data to file, updating total_samps_written
  1641. dz->process = GREV;
  1642. if((exit_status = write_samps(obuf,maxwrite,dz))<0)
  1643. return(exit_status);
  1644. dz->process = CRYSTAL;
  1645. }
  1646. }
  1647. }
  1648. return FINISHED;
  1649. }
  1650. /*************************** CALCULATE_TIME_PARAMS **************************/
  1651. int calculate_time_params(int *monosamptime,double x,double eventtime,dataptr dz)
  1652. {
  1653. double half_timewidth, time;
  1654. half_timewidth = dz->param[CRY_TWIDTH]/2.0;
  1655. time = eventtime + half_timewidth + (x * half_timewidth);
  1656. *monosamptime = (int)round(time * dz->infile->srate);
  1657. return FINISHED;
  1658. }
  1659. /*************************** CALCULATE_PITCH_AND_TIME_PARAMS **************************/
  1660. int calculate_pitch_and_time_params(double *midipitch,int *monosamptime,double x,double y,double eventtime,dataptr dz)
  1661. {
  1662. double half_timewidth, time, half_prange;
  1663. half_timewidth = dz->param[CRY_TWIDTH]/2.0;
  1664. time = eventtime + half_timewidth + (x * half_timewidth);
  1665. *monosamptime = (int)round(time * dz->infile->srate);
  1666. half_prange = (dz->param[CRY_PHI] - dz->param[CRY_PLO])/2.0;
  1667. *midipitch = dz->param[CRY_PLO] + half_prange + (y * half_prange);
  1668. return FINISHED;
  1669. }
  1670. /*************************** DELAY_TRANSPOSE_INPUT_SOUND **************************/
  1671. int delay_transpose_input_sound(double midipitch, int vertexno, dataptr dz)
  1672. {
  1673. // double frq, del, maxout, normaliser, absout, tabincr, tabpos, frac, diff;
  1674. // int sampdel, srclen, opos, outpos, ipos, tabsize, thispos, nextpos, n;
  1675. double frq, maxout, normaliser, absout, tabincr, tabpos, frac, diff;
  1676. int srclen, opos, thispos, nextpos, n;
  1677. float *ibuf, *trnsbuf = dz->sampbuf[TRNSBUF];
  1678. memset((char *)trnsbuf,0,dz->rampbrksize * sizeof(float));
  1679. if(dz->infilecnt > 1) {
  1680. ibuf = dz->sampbuf[THISIBUF + vertexno];
  1681. srclen = dz->insams[vertexno];
  1682. } else {
  1683. ibuf = dz->sampbuf[THISIBUF];
  1684. srclen = dz->insams[0];
  1685. }
  1686. if(midipitch < 0 || midipitch > 127) {
  1687. sprintf(errstr,"MIDI value out of range 0 - 127\n");
  1688. return(GOAL_FAILED);
  1689. }
  1690. tabincr = (double)srclen/(double)dz->infile->srate; // tabincr to read table once per second, i.e. at 1Hz
  1691. frq = miditohz(midipitch);
  1692. tabincr *= frq; // Frq-related table-read increment
  1693. tabpos = 0;
  1694. for(n = 0; n< dz->rampbrksize;n++) {
  1695. thispos = (int)floor(tabpos); // Read input sample by interpolation
  1696. nextpos = thispos+1; // with incr determined by pitch/frq
  1697. frac = tabpos - thispos;
  1698. diff = ibuf[nextpos] - ibuf[thispos];
  1699. diff *= frac;
  1700. trnsbuf[n] = (float)(ibuf[thispos] + diff);
  1701. tabpos += tabincr;
  1702. if(tabpos >= srclen)
  1703. tabpos -= srclen;
  1704. }
  1705. maxout = -1;
  1706. for(opos = 0; opos < dz->rampbrksize; opos++) { // Find max sample
  1707. absout = fabs(trnsbuf[opos]);
  1708. maxout = max(absout,maxout);
  1709. }
  1710. if(maxout > MAXCRYSLEVEL) {
  1711. normaliser = MAXCRYSLEVEL/maxout;
  1712. for(opos = 0; opos < dz->rampbrksize; opos++) // Normalise
  1713. trnsbuf[opos] = (float)(trnsbuf[opos] * normaliser);
  1714. }
  1715. return(FINISHED);
  1716. }
  1717. /*************************** FILTER_SOUND **************************/
  1718. int filter_sound(double z, dataptr dz)
  1719. {
  1720. int i;
  1721. float *trnsbuf = dz->sampbuf[TRNSBUF], *filtbuf = dz->sampbuf[FSBUF];
  1722. double val, filtsig_level, unfilt_siglevel, maxval, normaliser;
  1723. memset((char *)filtbuf,0,dz->rampbrksize * sizeof(float));
  1724. do_lphp_filter(dz); // Filters the transposed-snd in TRNSBUF, to FSBUF
  1725. z = -z; // Change range from -1 to <0 to >0 to 1
  1726. filtsig_level = pow(z,dz->param[CRY_FSLOPE]);
  1727. unfilt_siglevel = 1.0 - filtsig_level;
  1728. maxval = -1;
  1729. for (i = 0 ; i < dz->rampbrksize; i++) {
  1730. val = (trnsbuf[i] * unfilt_siglevel) + (filtbuf[i] * filtsig_level); // Mix filtered and unfiltered sound
  1731. trnsbuf[i] = (float)val;
  1732. maxval = max(fabs(val),maxval);
  1733. }
  1734. if(maxval > MAXCRYSLEVEL) {
  1735. normaliser = MAXCRYSLEVEL/maxval;
  1736. for (i = 0 ; i < dz->rampbrksize; i++) {
  1737. trnsbuf[i] = (float)(trnsbuf[i] * normaliser);
  1738. }
  1739. }
  1740. return FINISHED;
  1741. }
  1742. /*************************** CREATE_CRYSTAL_SNDBUFS **************************/
  1743. int create_crystal_sndbufs(dataptr dz)
  1744. {
  1745. int exit_status;
  1746. unsigned int bigbufsize, inbufssize;
  1747. int max_tw, n, m, eventlen, evbufsize;
  1748. double maxtw;
  1749. if(dz->sbufptr == 0 || dz->sampbuf==0) {
  1750. sprintf(errstr,"buffer pointers not allocated: create_sndbufs()\n");
  1751. return(PROGRAM_ERROR);
  1752. }
  1753. if(dz->brksize[CRY_TWIDTH]) {
  1754. if((exit_status = get_maxvalue_in_brktable(&maxtw,CRY_TWIDTH,dz))<0)
  1755. return exit_status;
  1756. } else
  1757. maxtw = dz->param[CRY_TWIDTH];
  1758. max_tw = (int)ceil(maxtw * (double)dz->infile->srate); // maximum time between first and last event onset within a time-set
  1759. eventlen = dz->rampbrksize; // duration of event(s) in timeset
  1760. dz->buflen = (max_tw + /* final */ eventlen) * dz->outchans; // Scale up from mono to number of output chans
  1761. dz->buflen += SAFETY;
  1762. inbufssize = 0;
  1763. for(n=0;n<dz->infilecnt;n++)
  1764. inbufssize += dz->insams[n] + 1; // Add wrap-around point
  1765. evbufsize = dz->rampbrksize; // Store size of envelope, in samples
  1766. bigbufsize = (dz->buflen * 2) + (evbufsize * 4) + inbufssize; // Need space for outbuf & overflowbuf
  1767. if((dz->bigbuf = (float *)malloc(bigbufsize * sizeof(float))) == NULL) {
  1768. sprintf(errstr,"INSUFFICIENT MEMORY to create sound buffers.\n");
  1769. return(PROGRAM_ERROR);
  1770. }
  1771. // MONO
  1772. // obuf ovflwbuf transposed event enveloped event filt/stack raw-envelope input sound
  1773. // obuf ovflwbuf trnsbuf envbuf fsbuf ebuf ibufs...
  1774. // 0 1 2 3 4 5 6 (7 etc)
  1775. // |-----------|--------------|------------------|------------------|------------|-------------|---------------|---------------|
  1776. //
  1777. // buflen buflen evbufsize evbufsize evbufsize evbufsize insams[0]+1 (insams[1]+1 etc)
  1778. //
  1779. // Read from inbuf, transpose into transposedeventbuf, but only as far as end of buf
  1780. // Envelope result into envelopedeventbuf (using sample-scale raw-envelope in "envelope")
  1781. // Add event to obuf (in multichan format if ness)
  1782. // If next group-of-writes start in overflwbuf, write obuf, and copy ovflwbuf->obuf, and zero ovflwbuf
  1783. // BUT NB ...
  1784. // i t f f+t e
  1785. // If filtering used .... filter BEFORE enveloping (and curtail output to buffer size) 6->2->4->2->3 write to obuf from 3
  1786. // i t e s e+s(NORMD)
  1787. // If stack used .......... stack AFTER enveloping (so stack is no longer than evbufsize) 6->2->3->4->3 write to obuf from 3
  1788. n = 0;
  1789. dz->sbufptr[n] = dz->sampbuf[n] = dz->bigbuf; // obuf [0] // 0 = Output buffer
  1790. n++; // size buflen
  1791. dz->sbufptr[n] = dz->sampbuf[n] = dz->sampbuf[n-1] + dz->buflen; // ovflwbuf [1] // 1 = overflow buffer
  1792. n++; // size buflen
  1793. dz->sbufptr[n] = dz->sampbuf[n] = dz->sampbuf[n-1] + dz->buflen; // trnsbuf [2] // 2 = created event (transposition of ibuf)
  1794. n++; // size evbufsize
  1795. dz->sbufptr[n] = dz->sampbuf[n] = dz->sampbuf[n-1] + evbufsize; // envbuf [3] // 3 = enveloped event
  1796. n++; // size evbufsize
  1797. dz->sbufptr[n] = dz->sampbuf[n] = dz->sampbuf[n-1] + evbufsize; // fsbuf [4] // 4 = filtered or stacked
  1798. n++; // size evbufsize
  1799. dz->sbufptr[n] = dz->sampbuf[n] = dz->sampbuf[n-1] + evbufsize; // ebuf [5] // 5 = raw envelope
  1800. n++; // size evbufsize
  1801. dz->sbufptr[n] = dz->sampbuf[n] = dz->sampbuf[n-1] + evbufsize; // ibuf [6] // 6 = 1st insndbuf
  1802. if(dz->infilecnt > 1) { // size insams[0]
  1803. for(m=1;m<dz->infilecnt;m++) { // +ibufs [7.....]
  1804. n++; // 7etc = more insndbufs
  1805. dz->sbufptr[n] = dz->sampbuf[n] = dz->sampbuf[n-1] + (dz->insams[m-1] + 1); // size insams[m]
  1806. }
  1807. }
  1808. return(FINISHED);
  1809. }
  1810. /************************************* CRYSTAL_PARAM_PREPROCESS ***********************************
  1811. *
  1812. * (1) Read input file(s) to buffer(s), with wraparound point, for reading as a waveform table.
  1813. * (2) Convert input envelope to a sample scale array in another buffer.
  1814. */
  1815. int crystal_param_preprocess(dataptr dz)
  1816. {
  1817. int exit_status;
  1818. double *env = dz->parray[ENV_DATA], maxval = -1;
  1819. int n, sampsread, dovelen;
  1820. double srate = (double)dz->infile->srate, val, thistime;
  1821. int origbuflen = dz->buflen, nextind;
  1822. float *ibuf = dz->sampbuf[THISIBUF];
  1823. float *ebuf = dz->sampbuf[EBUF];
  1824. dovelen = (int)(CRY_DOVE * (double)dz->infile->srate);
  1825. // For multiple input files
  1826. for(n = 0; n< dz->infilecnt;n++) {
  1827. if(dz->insams[n] <= dovelen * 2.0) {
  1828. sprintf(errstr,"Input file %d too short for start-and-end dovetails (min size %lf secs)\n",n+1,CRY_DOVE * 2);
  1829. return DATA_ERROR;
  1830. }
  1831. dz->buflen = dz->insams[n]; // Read input sound(s) to ibuf(s)
  1832. ibuf = dz->sampbuf[THISIBUF+n];
  1833. memset((char *)ibuf,0,dz->buflen * sizeof(float));
  1834. if((sampsread = fgetfbufEx(ibuf, dz->buflen,dz->ifd[n],0)) < 0) {
  1835. sprintf(errstr,"Can't read samples from input soundfile %d.\n",n+1);
  1836. return(SYSTEM_ERROR);
  1837. }
  1838. ibuf[dz->buflen] = 0; // Wrap-around zero-point
  1839. }
  1840. dz->buflen = origbuflen;
  1841. dovetail(dovelen,dz); // Dovetail input sounds
  1842. dz->stackpeak = 0;
  1843. nextind = 2; // Read input envelope array into a sample-scale array in a buffer
  1844. for(n = 0; n < dz->rampbrksize; n++) {
  1845. thistime = (double)n/srate;
  1846. if((exit_status = read_value_from_brkarray(env,&nextind,&val,thistime,dz))<0)
  1847. return exit_status;
  1848. ebuf[n] = (float)val;
  1849. if(fabs(val) > maxval) { // Find loudest point in envelope (for stacking)
  1850. maxval = fabs(val);
  1851. dz->stackpeak = n;
  1852. }
  1853. }
  1854. return FINISHED;
  1855. }
  1856. /**************************** READ_VALUE_FROM_BRKARRAY *****************************/
  1857. int read_value_from_brkarray(double *env,int *nextind,double *val,double time,dataptr dz)
  1858. {
  1859. double thistim, nexttim, thisval, nextval, valdiff, timdiff, timfrac;
  1860. nexttim = env[*nextind];
  1861. while(time > nexttim) {
  1862. if((*nextind += 2) >= dz->envdatalen) {
  1863. sprintf(errstr, "Overshot end of envelope brktable while converting to sample-buffer.\n");
  1864. return PROGRAM_ERROR;
  1865. }
  1866. nexttim = env[*nextind];
  1867. }
  1868. thistim = env[*nextind - 2];
  1869. thisval = env[*nextind - 1];
  1870. nextval = env[*nextind + 1];
  1871. valdiff = nextval - thisval;
  1872. timdiff = nexttim - thistim;
  1873. timfrac = (time - thistim)/timdiff;
  1874. valdiff *= timfrac;
  1875. *val = thisval + valdiff;
  1876. return FINISHED;
  1877. }
  1878. /********************************* SETUP_LPHP_FILTER *****************************/
  1879. int setup_lphp_filter(dataptr dz)
  1880. {
  1881. int exit_status;
  1882. int filter_order;
  1883. double signd = -1.0; /* low pass */
  1884. filter_order = establish_order_of_filter(dz);
  1885. if((exit_status = allocate_internal_params_lphp(dz))<0)
  1886. return(exit_status);
  1887. calculate_filter_poles_lphp(signd,filter_order,dz);
  1888. initialise_filter_coeffs_lphp(dz);
  1889. fflush(stdout);
  1890. return(FINISHED);
  1891. }
  1892. /********************************* ESTABLISH_ORDER_OF_FILTER *****************************/
  1893. int establish_order_of_filter(dataptr dz)
  1894. {
  1895. int filter_order;
  1896. double tc, tp, tt, pii, xx, yy;
  1897. double sr = (double)dz->infile->srate;
  1898. if (dz->param[CRY_FPASS] < dz->param[CRY_FSTOP]) /* low pass */
  1899. dz->param[CRY_MUL] = 2.0;
  1900. else {
  1901. dz->param[CRY_MUL] = -2.0;
  1902. dz->param[CRY_FPASS] = dz->nyquist - dz->param[CRY_FPASS];
  1903. dz->param[CRY_FSTOP] = dz->nyquist - dz->param[CRY_FSTOP];
  1904. }
  1905. pii = 4.0 * atan(1.0);
  1906. dz->param[CRY_FPASS] = pii * dz->param[CRY_FPASS]/sr;
  1907. tp = tan(dz->param[CRY_FPASS]);
  1908. dz->param[CRY_FSTOP] = pii * dz->param[CRY_FSTOP]/sr;
  1909. tc = tan(dz->param[CRY_FSTOP]);
  1910. tt = tc / tp ;
  1911. tt = (tt * tt);
  1912. dz->param[CRY_FATT] = fabs(dz->param[CRY_FATT]);
  1913. dz->param[CRY_FATT] = dz->param[CRY_FATT] * log(10.0)/10.0 ;
  1914. dz->param[CRY_FATT] = exp(dz->param[CRY_FATT]) - 1.0 ;
  1915. xx = log(dz->param[CRY_FATT])/log(tt) ;
  1916. yy = floor(xx);
  1917. if ((xx - yy) == 0.0 )
  1918. yy = yy - 1.0 ;
  1919. filter_order = ((int)yy) + 1;
  1920. if (filter_order <= 1)
  1921. filter_order = 2;
  1922. dz->iparam[CRY_CNT] = filter_order/2 ;
  1923. filter_order = 2 * dz->iparam[CRY_CNT] ;
  1924. fprintf(stdout,"INFO: Order of filter is %d\n", filter_order);
  1925. fflush(stdout);
  1926. dz->iparam[CRY_CNT] = min(dz->iparam[CRY_CNT],CRY_LBF);
  1927. filter_order = 2 * dz->iparam[CRY_CNT];
  1928. return(filter_order);
  1929. }
  1930. /********************************* ALLOCATE_INTERNAL_PARAMS_LPHP *****************************/
  1931. int allocate_internal_params_lphp(dataptr dz)
  1932. {
  1933. if((dz->parray[CRY_DEN1] = (double *)malloc(dz->iparam[CRY_CNT] * sizeof(double)))==NULL
  1934. || (dz->parray[CRY_DEN2] = (double *)malloc(dz->iparam[CRY_CNT] * sizeof(double)))==NULL
  1935. || (dz->parray[CRY_CN] = (double *)malloc(dz->iparam[CRY_CNT] * sizeof(double)))==NULL
  1936. || (dz->parray[CRY_S1] = (double *)malloc(dz->iparam[CRY_CNT] * sizeof(double)))==NULL
  1937. || (dz->parray[CRY_E1] = (double *)malloc(dz->iparam[CRY_CNT] * sizeof(double)))==NULL
  1938. || (dz->parray[CRY_S2] = (double *)malloc(dz->iparam[CRY_CNT] * sizeof(double)))==NULL
  1939. || (dz->parray[CRY_E2] = (double *)malloc(dz->iparam[CRY_CNT] * sizeof(double)))==NULL) {
  1940. sprintf(errstr,"INSUFFICIENT MEMORY for arrays of filter parameters.\n");
  1941. return(MEMORY_ERROR);
  1942. }
  1943. return(FINISHED);
  1944. }
  1945. /********************************* CALCULATE_FILTER_POLES_LPHP *****************************/
  1946. void calculate_filter_poles_lphp(double signd,int filter_order,dataptr dz)
  1947. {
  1948. double ss, xx, aa, tppwr, x1, x2, cc;
  1949. double pii = 4.0 * atan(1.0);
  1950. double tp = tan(dz->param[CRY_FPASS]);
  1951. int k;
  1952. ss = pii / (double)(2 * filter_order);
  1953. for (k = 0; k < dz->iparam[CRY_CNT]; k++ ) {
  1954. xx = (double) ((2.0 * (k+1)) - 1.0);
  1955. aa = -sin(xx * ss);
  1956. tppwr = pow(tp,2.0);
  1957. cc = 1.0 - (2.0 * aa * tp) + tppwr;
  1958. x1 = 2.0 * (tppwr - 1.0)/cc ;
  1959. x2 = (1.0 + (2.0 * aa * tp) + tppwr)/cc ;
  1960. dz->parray[CRY_DEN1][k] = signd * x1;
  1961. dz->parray[CRY_DEN2][k] = -x2 ;
  1962. dz->parray[CRY_CN][k] = pow(tp,2.0)/cc ;
  1963. }
  1964. }
  1965. /********************************* INITIALISE_FILTER_COEFFS_LPHP *****************************/
  1966. void initialise_filter_coeffs_lphp(dataptr dz)
  1967. {
  1968. int k;
  1969. for (k = 0 ; k < dz->iparam[CRY_CNT]; k++) {
  1970. dz->parray[CRY_S1][k] = 0.0;
  1971. dz->parray[CRY_S2][k] = 0.0;
  1972. dz->parray[CRY_E1][k] = 0.0;
  1973. dz->parray[CRY_E2][k] = 0.0;
  1974. }
  1975. }
  1976. /***************************** DO_LPHP_FILTER *************************************/
  1977. void do_lphp_filter(dataptr dz)
  1978. {
  1979. double *e1 = dz->parray[CRY_E1];
  1980. double *e2 = dz->parray[CRY_E2];
  1981. double *s1 = dz->parray[CRY_S1];
  1982. double *s2 = dz->parray[CRY_S2];
  1983. double *den1 = dz->parray[CRY_DEN1];
  1984. double *den2 = dz->parray[CRY_DEN2];
  1985. double *cn = dz->parray[CRY_CN];
  1986. int i, hasreported = 0;
  1987. int k;
  1988. float *trnsbuf = dz->sampbuf[TRNSBUF], *filtbuf = dz->sampbuf[FSBUF];
  1989. double ip, op = 0.0, b1;
  1990. for (i = 0 ; i < dz->rampbrksize; i++) {
  1991. ip = (double) trnsbuf[i];
  1992. for (k = 0 ; k < dz->iparam[CRY_CNT]; k++) {
  1993. b1 = dz->param[CRY_MUL] * cn[k];
  1994. op = (cn[k] * ip) + (den1[k] * s1[k]) + (den2[k] * s2[k]) + (b1 * e1[k]) + (cn[k] * e2[k]);
  1995. s2[k] = s1[k];
  1996. s1[k] = op;
  1997. e2[k] = e1[k];
  1998. e1[k] = ip;
  1999. }
  2000. op *= dz->param[CRY_FPRESC];
  2001. if (fabs(op) > 1.0) {
  2002. #ifdef DOTEST
  2003. if(!hasreported) {
  2004. fprintf(stdout,"INFO: Overflow in Lowpass filter.\n");
  2005. fflush(stdout);
  2006. hasreported = 1;
  2007. }
  2008. #endif
  2009. dz->param[CRY_FPRESC] *= .9999;
  2010. if (op > 0.0)
  2011. op = 1.0;
  2012. else
  2013. op = -1.0;
  2014. }
  2015. filtbuf[i] = (float)op;
  2016. }
  2017. }
  2018. /******************************** VALID_VECTORLEN *********************************/
  2019. int get_vectorlen(double *vectorelen,double x,double y,double z)
  2020. {
  2021. double sum;
  2022. sum = (x*x) + (y*y) + (z*z);
  2023. *vectorelen = sqrt(sum);
  2024. if(*vectorelen > 1.0) // i.e. sqrt(sum) > 1.0
  2025. return -1;
  2026. return 1;
  2027. }
  2028. /******************************** ENVELOPE_SOUND *********************************/
  2029. int envelope_sound(int do_normalise,dataptr dz)
  2030. {
  2031. int i;
  2032. double maxval = -1.0, normaliser, val;
  2033. float *trnsbuf = dz->sampbuf[TRNSBUF], *envbuf = dz->sampbuf[ENVBUF], *ebuf = dz->sampbuf[EBUF];
  2034. memset((char *)envbuf,0,dz->rampbrksize * sizeof(float));
  2035. if(do_normalise) {
  2036. for(i=0; i <dz->rampbrksize; i++) {
  2037. val = trnsbuf[i] * ebuf[i];
  2038. maxval = max(maxval,fabs(val));
  2039. envbuf[i] = (float)val; // Enveloped sound into ENVBUF
  2040. }
  2041. if(maxval > MAXCRYSLEVEL) {
  2042. normaliser = MAXCRYSLEVEL/maxval;
  2043. for(i=0; i <dz->rampbrksize; i++)
  2044. envbuf[i] = (float)(envbuf[i] * normaliser);
  2045. }
  2046. } else {
  2047. for(i=0; i <dz->rampbrksize; i++)
  2048. envbuf[i] = (float)(trnsbuf[i] * ebuf[i]);
  2049. }
  2050. return FINISHED;
  2051. }
  2052. /******************************** STACK_ENVELD_SND *********************************/
  2053. int stack_enveld_snd(double closeness,dataptr dz)
  2054. {
  2055. float *envbuf = dz->sampbuf[ENVBUF], *fsbuf = dz->sampbuf[FSBUF], *transbuf = dz->sampbuf[TRNSBUF];
  2056. int offset = dz->stackpeak/2, i;
  2057. double maxval, octup_level, twooctup_level, src_level, val, normaliser;
  2058. memset((char *)fsbuf,0,dz->rampbrksize * sizeof(float));
  2059. memset((char *)transbuf,0,dz->rampbrksize * sizeof(float));
  2060. for(i=0; i <dz->rampbrksize; i+=2) { // Transpose enveld snd by 8va up, offset so peak of envelopes,
  2061. if(offset >= dz->rampbrksize) { // in transposed and untransposed sounds, coincide.
  2062. sprintf(errstr,"Stacking produced overflow of fsbuf.\n");
  2063. return PROGRAM_ERROR;
  2064. }
  2065. fsbuf[offset++] = envbuf[i];
  2066. }
  2067. offset = dz->stackpeak * 3;
  2068. offset = offset/4;
  2069. for(i=0; i <dz->rampbrksize; i+=4) { // Transpose enveld snd by TWO 8va up, offset so peak of envelopes,
  2070. if(offset >= dz->rampbrksize) { // in transposed and untransposed sounds, coincide.
  2071. sprintf(errstr,"Stacking produced overflow of fsbuf.\n");
  2072. return PROGRAM_ERROR;
  2073. }
  2074. transbuf[offset++] = envbuf[i];
  2075. }
  2076. maxval = -1;
  2077. octup_level = pow(closeness,dz->param[CRY_SSLOPE]) * MAX_PROPORTION_8UP_IN_STAK;
  2078. twooctup_level= pow(closeness,(dz->param[CRY_SSLOPE] * CRY_STKFAC)) * MAX_PROPORTION_8UP_IN_STAK;
  2079. src_level = 1.0 - octup_level;
  2080. for(i=0; i <dz->rampbrksize; i++) { // Mix orig and 8va transposed sounds
  2081. val = (envbuf[i] * src_level) + (fsbuf[i] * octup_level) + (transbuf[i] * twooctup_level);
  2082. envbuf[i] = (float)val;
  2083. maxval = max(maxval,fabs(val));
  2084. }
  2085. if(maxval > MAXCRYSLEVEL) {
  2086. normaliser = MAXCRYSLEVEL/maxval;
  2087. for(i=0; i <dz->rampbrksize; i++)
  2088. envbuf[i] = (float)(envbuf[i] * normaliser);
  2089. }
  2090. return FINISHED;
  2091. }
  2092. /******************************** CHECK_POSITION_OF_SOUND_IN_OUTPUT_BUF ********************************
  2093. *
  2094. * Check if the earliest of the event in the event-group is beyond the current buffer end
  2095. * and if so, write (or get max of) buffer, and advance buffers.
  2096. */
  2097. int check_position_of_event_group_in_output_buf(int passno,double *maxlevel,int *maxwrite,int minsamptime,double normaliser,dataptr dz) // (check overflows - write to outfile)
  2098. {
  2099. int exit_status;
  2100. int absopos, i; // Absolute position of write-position in output file
  2101. float *obuf = dz->sampbuf[THISOBUF], *ovflwbuf = dz->sampbuf[OVFLWBUF];
  2102. switch(dz->mode) {
  2103. case(0): absopos = minsamptime; break; // MONO
  2104. case(1): absopos = minsamptime * 2; break; // STEREO
  2105. default: absopos = minsamptime * ALL_CHANS; break; // 8-CHAN
  2106. }
  2107. while(absopos > dz->total_samps_written + dz->buflen) { // If current write-start is beyond end of current buffer
  2108. if(passno == 0) {
  2109. for(i=0;i < dz->buflen;i++)
  2110. *maxlevel = max(*maxlevel,fabs(obuf[i])); // write data to file, updating total_samps_written
  2111. dz->total_samps_written += dz->buflen;
  2112. dz->process = GREV;
  2113. display_virtual_time(0,dz);
  2114. dz->process = CRYSTAL;
  2115. } else { // This could involve writing silent buffers
  2116. if(normaliser != 1.0) {
  2117. for(i=0;i < dz->buflen;i++)
  2118. obuf[i] = (float)(obuf[i] * normaliser);
  2119. }
  2120. dz->process = GREV;
  2121. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2122. return(exit_status);
  2123. dz->process = CRYSTAL;
  2124. }
  2125. for(i=0;i < dz->buflen;i++) // Copy overflow back into obuf
  2126. obuf[i] = ovflwbuf[i]; // and zero overflow
  2127. memset((char *)ovflwbuf,0,dz->buflen * sizeof(float));
  2128. *maxwrite -= dz->buflen;
  2129. }
  2130. return FINISHED;
  2131. }
  2132. /******************************** WRITE_SOUND_INTO_OUTPUT_BUF ********************************/
  2133. int write_sound_into_output_buf(int monosamptime,int minsamptime,double x,int eightrot,int *maxwrite, dataptr dz)
  2134. {
  2135. int absopos; // Absolute position of write-position in output file
  2136. int opos, i, leftopos, rightopos;
  2137. double leftgain = 0.0, rightgain = 0.0, val;
  2138. float *obuf = dz->sampbuf[THISOBUF], *envbuf = dz->sampbuf[ENVBUF];
  2139. switch(dz->mode) {
  2140. case(0): absopos = monosamptime; break; // MONO
  2141. case(1): absopos = monosamptime * 2; break; // STEREO
  2142. default: absopos = monosamptime * ALL_CHANS; break; // 8-CHAN
  2143. }
  2144. if(dz->mode == 9)
  2145. opos = (monosamptime - minsamptime) * 2; // New buffer for each vertex-set, and stereo
  2146. else
  2147. opos = absopos - dz->total_samps_written;
  2148. switch(dz->mode) {
  2149. case(0): // MONO
  2150. for(i=0;i < dz->rampbrksize;i++) { // The buffer + overflow is always bigger than dz->rampbrksize = size of single event
  2151. obuf[opos] = (float)(obuf[opos] + envbuf[i]); // + the total width of the event-group
  2152. opos++;
  2153. }
  2154. *maxwrite = max(*maxwrite,opos);
  2155. break;
  2156. case(1):
  2157. case(9): // STEREO
  2158. pancalc(x,&leftgain,&rightgain);
  2159. for(i=0;i < dz->rampbrksize;i++) {
  2160. val = obuf[opos] + (envbuf[i] * leftgain);
  2161. obuf[opos++] = (float)val;
  2162. val = obuf[opos] + (envbuf[i] * rightgain);
  2163. obuf[opos++] = (float)val;
  2164. }
  2165. *maxwrite = max(*maxwrite,opos);
  2166. break;
  2167. default:
  2168. leftopos = opos + eightrot;
  2169. switch(dz->mode) {
  2170. case(2):
  2171. case(3):
  2172. case(4):
  2173. case(5): // STEREO-BETWEEN NON-ADJACENT CHANS IN 8-CHAN SPACE
  2174. if((rightopos = leftopos + 2) >= ALL_CHANS)
  2175. rightopos -= ALL_CHANS;
  2176. break;
  2177. default: // STEREO-BETWEEN ADJACENT CHANS IN 8-CHAN SPACE
  2178. if((rightopos = leftopos + 1) >= ALL_CHANS)
  2179. rightopos -= ALL_CHANS;
  2180. break;
  2181. }
  2182. pancalc(x,&leftgain,&rightgain);
  2183. for(i=0;i < dz->rampbrksize;i++) {
  2184. val = obuf[leftopos] + (envbuf[i] * leftgain);
  2185. obuf[leftopos] = (float)val;
  2186. val = obuf[rightopos] + (envbuf[i] * rightgain);
  2187. obuf[rightopos] = (float)val;
  2188. leftopos += ALL_CHANS;
  2189. rightopos += ALL_CHANS;
  2190. }
  2191. *maxwrite = max(*maxwrite,opos+ALL_CHANS);
  2192. }
  2193. return FINISHED;
  2194. }
  2195. /************************ HANDLE_THE_EXTRA_INFILES *********************/
  2196. int handle_the_extra_infiles(char ***cmdline,int *cmdlinecnt,dataptr dz)
  2197. {
  2198. /* OPEN ANY FURTHER INFILES, CHECK COMPATIBILITY, STORE DATA AND INFO */
  2199. int exit_status, n;
  2200. char *filename;
  2201. if(dz->infilecnt > 1) {
  2202. for(n=1;n<dz->infilecnt;n++) {
  2203. filename = (*cmdline)[0];
  2204. if((exit_status = handle_other_infile(n,filename,dz))<0)
  2205. return(exit_status);
  2206. (*cmdline)++;
  2207. (*cmdlinecnt)--;
  2208. }
  2209. }
  2210. return(FINISHED);
  2211. }
  2212. /************************************ PANCALC *******************************/
  2213. void pancalc(double position,double *leftgain,double *rightgain)
  2214. {
  2215. int dirflag;
  2216. double temp;
  2217. double relpos;
  2218. double reldist, invsquare;
  2219. if(position < 0.0)
  2220. dirflag = SIGNAL_TO_LEFT; /* signal on left */
  2221. else
  2222. dirflag = SIGNAL_TO_RIGHT;
  2223. if(position < 0)
  2224. relpos = -position;
  2225. else
  2226. relpos = position;
  2227. if(relpos <= 1.0){ /* between the speakers */
  2228. temp = 1.0 + (relpos * relpos);
  2229. reldist = ROOT2 / sqrt(temp);
  2230. temp = (position + 1.0) / 2.0;
  2231. *rightgain = temp * reldist;
  2232. *leftgain = (1.0 - temp ) * reldist;
  2233. } else { /* outside the speakers */
  2234. temp = (relpos * relpos) + 1.0;
  2235. reldist = sqrt(temp) / ROOT2; /* relative distance to source */
  2236. invsquare = 1.0 / (reldist * reldist);
  2237. if(dirflag == SIGNAL_TO_LEFT){
  2238. *leftgain = invsquare;
  2239. *rightgain = 0.0;
  2240. } else { /* SIGNAL_TO_RIGHT */
  2241. *rightgain = invsquare;
  2242. *leftgain = 0;
  2243. }
  2244. }
  2245. }
  2246. /********************************** DOPERM etc *******************************/
  2247. void doperm(int *perm,int permlen)
  2248. {
  2249. int n, t;
  2250. for(n=0;n<permlen;n++) {
  2251. t = (int)floor(drand48() * (n+1));
  2252. if(t==n) {
  2253. hprefix(n,perm,permlen);
  2254. } else {
  2255. hinsert(n,t,perm,permlen);
  2256. }
  2257. }
  2258. }
  2259. void hinsert(int m,int t,int *perm,int permlen)
  2260. {
  2261. hshuflup(t+1,perm,permlen);
  2262. perm[t+1] = m;
  2263. }
  2264. void hprefix(int m,int *perm,int permlen)
  2265. {
  2266. hshuflup(0,perm,permlen);
  2267. perm[0] = m;
  2268. }
  2269. void hshuflup(int k,int *perm,int permlen)
  2270. {
  2271. int n, *i;
  2272. int z = permlen - 1;
  2273. i = perm+z;
  2274. for(n = z;n > k;n--) {
  2275. *i = *(i-1);
  2276. i--;
  2277. }
  2278. }
  2279. /********************************** ROTATE_VERTEX *******************************
  2280. *
  2281. * If the original coordinates of a point (on a sphere) are x.y.z
  2282. * then a rotation about the z-axis of X radians is given by matrix
  2283. *
  2284. * cos(X) sin(x) 0
  2285. * -sin(X) cos(X) 0
  2286. * 0 0 1
  2287. *
  2288. * This creates new points (xx,yy,zz) thus
  2289. *
  2290. * xx = cos(X)*x + sin(X)*y + 0*z
  2291. * yy = -sin(X)*x + cos(X)*y + 0*z
  2292. * zz = 0*x + 0*y + 1*z
  2293. *
  2294. *
  2295. * For a rotation around the y axis of Y radians, matrix is
  2296. *
  2297. * cos(Y) 0 sin(Y)
  2298. * 0 1 0
  2299. * -sin(Y) 0 cos(Y)
  2300. *
  2301. * This creates new points (x',y',z') thus
  2302. *
  2303. * x' = cos(Y)*xx + 0*yy + sin(Y)*zz
  2304. * y' = 0*xx + 1*yy + 0*zz
  2305. * z' = -sin(Y)*xx + 0*yy + cos(Y)*zz
  2306. *
  2307. * X and Y pre-calculated from the angular rotation speeds, and timestep, and applied successively.
  2308. */
  2309. void rotate_vertex(double *x,double *y,double *z,double rotation_in_xy_plane,double rotation_in_xz_plane,int vertexno,double eventtime,int *warning)
  2310. {
  2311. double xx, yy, zz, adjust, vectorlen;
  2312. // Rotate around z axis - in xy plane
  2313. xx = cos(rotation_in_xy_plane) * (*x);
  2314. xx += sin(rotation_in_xy_plane) * (*y);
  2315. xx = min(xx,1.0); // Avoid rounding errors
  2316. xx = max(xx,-1.0);
  2317. yy = -sin(rotation_in_xy_plane) * (*x);
  2318. yy += cos(rotation_in_xy_plane) * (*y);
  2319. yy = min(yy,1.0);
  2320. yy = max(yy,-1.0);
  2321. zz = *z;
  2322. // Rotate around y axis - in xz plane
  2323. *x = cos(rotation_in_xz_plane) * xx;
  2324. *x += sin(rotation_in_xz_plane) * zz;
  2325. *x = min(*x,1.0);
  2326. *x = max(*x,-1.0);
  2327. *y = yy;
  2328. *z = -sin(rotation_in_xz_plane) * xx;
  2329. *z += cos(rotation_in_xz_plane) * zz;
  2330. *z = min(*z,1.0);
  2331. *z = max(*z,-1.0);
  2332. if((get_vectorlen(&vectorlen,*x,*y,*z))<0) {
  2333. if(*warning == 0) {
  2334. fprintf(stdout,"WARNING: rotated vector %d lies outside unit sphere at time %lf : coords %lf %lf %lf len %.16lf\n",
  2335. vertexno+1,eventtime,*x,*y,*z,vectorlen);
  2336. fflush(stdout);
  2337. *warning = 1;
  2338. }
  2339. adjust = ((*x)*(*x)) + ((*y)*(*y)) + ((*z)*(*z));
  2340. adjust = sqrt(adjust);
  2341. adjust = 1.0/adjust;
  2342. *x *= adjust;
  2343. *y *= adjust;
  2344. *z *= adjust;
  2345. }
  2346. }
  2347. /*************************************** DOVETAIL **********************************/
  2348. void dovetail(int dovelen, dataptr dz)
  2349. {
  2350. float *buf;
  2351. double splice;
  2352. int /* buflen,*/ i, j, n;
  2353. for(n= 0; n < dz->infilecnt; n++) {
  2354. buf = dz->sampbuf[THISIBUF+n];
  2355. // buflen = dz->insams[n] + 1;
  2356. for(i = 0, j = dz->insams[n]; i < dovelen; i++,j--) {
  2357. splice = (double)i/(double)dovelen;
  2358. buf[i] = (float)(buf[i] * splice);
  2359. buf[j] = (float)(buf[j] * splice);
  2360. }
  2361. }
  2362. }
  2363. /*************************************** WRITE_ROTATED_CRYSTAL_SOUND **********************************/
  2364. int write_rotated_crystal_sound(float *obuf,int maxwrite, dataptr dz)
  2365. {
  2366. int exit_status;
  2367. char temp[8];
  2368. if(dz->outcnt > 0) { // If not first file being written
  2369. if((exit_status = headwrite(dz->ofd,dz))<0) // Conclude and close last file
  2370. return(exit_status);
  2371. if((exit_status = reset_peak_finder(dz))<0)
  2372. return(exit_status);
  2373. if(sndcloseEx(dz->ofd) < 0) {
  2374. fprintf(stdout,"WARNING: Can't close output soundfile %s\n",dz->outfilename);
  2375. fflush(stdout);
  2376. }
  2377. dz->ofd = -1;
  2378. strcpy(dz->outfilename,dz->wordstor[0]); // Create name of this new file
  2379. sprintf(temp,"%d",dz->outcnt);
  2380. strcat(dz->outfilename,temp);
  2381. strcat(dz->outfilename,".wav"); // Create new outfile
  2382. dz->infile->channels = 2;
  2383. if((exit_status = create_sized_outfile(dz->outfilename,dz))<0)
  2384. return exit_status;
  2385. dz->infile->channels = 1;
  2386. }
  2387. dz->process = GREV;
  2388. if((exit_status = write_samps(obuf,maxwrite,dz))<0) // Write to outfile (whether a new file or not)
  2389. return(exit_status);
  2390. dz->process = CRYSTAL;
  2391. memset((char *)obuf,0,dz->buflen * sizeof(float)); // Reset the outputbuffer to zero, ready for next vertex-set
  2392. dz->outcnt++;
  2393. return FINISHED;
  2394. }