phasor.c 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521
  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. /* GO TO HEREH
  22. *
  23. * The write procedure not quite correct when there is offset.
  24. * Need to write to obuf UP to the "maxoffset"
  25. * BUT advance the obufotr only up to end of "towrite" WITHOUT the offset.
  26. * and ONLY WRITE TO FILE when obfptr is AT or BEYOND buflen AT ~START~ OF THE WRITE
  27. * (not simply when the write itself will overflow the buflen)
  28. *
  29. * Probably also need to extend obuf by another buflen.
  30. */
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <structures.h>
  34. #include <tkglobals.h>
  35. #include <pnames.h>
  36. #include <filetype.h>
  37. #include <processno.h>
  38. #include <modeno.h>
  39. #include <logic.h>
  40. #include <globcon.h>
  41. #include <cdpmain.h>
  42. #include <math.h>
  43. #include <mixxcon.h>
  44. #include <osbind.h>
  45. #include <standalone.h>
  46. #include <ctype.h>
  47. #include <sfsys.h>
  48. #include <string.h>
  49. #include <srates.h>
  50. #ifdef unix
  51. #define round(x) lround((x))
  52. #endif
  53. char errstr[2400];
  54. #define ibuflen itemcnt
  55. int anal_infiles = 1;
  56. int sloom = 0;
  57. int sloombatch = 0;
  58. const char* cdp_version = "6.1.0";
  59. #define MAXOUTLEVEL (0.95)
  60. #define WRAP (16) // wraparound extension of input buffer to allow for interpolated reading of last sample
  61. #define SAFETY (64) // Avoid overwriting end of arrays
  62. #define SIGNAL_TO_LEFT (0)
  63. #define SIGNAL_TO_RIGHT (1)
  64. #define ROOT2 (1.4142136)
  65. #define maxoffset total_windows // max time-offset of streams
  66. #define outchinfo is_mapping // lowest array number holding output-channel-info for each stream
  67. //CDP LIB REPLACEMENTS
  68. static int check_phasor_param_validity_and_consistency(double *maxoffset,dataptr dz);
  69. static int setup_phasor_application(dataptr dz);
  70. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  71. static int parse_infile_and_check_type(char **cmdline,dataptr dz);
  72. static int setup_phasor_param_ranges_and_defaults(dataptr dz);
  73. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz);
  74. static int open_the_outfile(dataptr dz);
  75. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  76. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  77. static int establish_application(dataptr dz);
  78. static int initialise_vflags(dataptr dz);
  79. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  80. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  81. static int mark_parameter_types(dataptr dz,aplptr ap);
  82. static int assign_file_data_storage(int infilecnt,dataptr dz);
  83. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  84. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  85. //static int get_the_mode_from_cmdline(char *str,dataptr dz);
  86. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  87. static int create_phasor_sndbufs(int maxshiftslen,double maxoffset,int *offsetwrap,dataptr dz);
  88. static int create_phaseshift_and_outchan_data_arrays(int *maxshiftslen, dataptr dz);
  89. static int calculate_phase_shifts(double time, int *phaseshiftcnt, dataptr dz);
  90. static int calculate_streams(double time,int phaseshiftcnt, int *obufpos, int *ibufpos, int passno, double normaliser, double *maxsamp,int offsetwrap,int * absolute_endofwrite,dataptr dz);
  91. static void pancalc(double position,double *leftgain,double *rightgain);
  92. static int phasor(int offsetwrap,dataptr dz);
  93. /**************************************** MAIN *********************************************/
  94. int main(int argc,char *argv[])
  95. {
  96. int exit_status;
  97. dataptr dz = NULL;
  98. char **cmdline;
  99. int cmdlinecnt;
  100. int n, maxshiftslen = 0, offsetwrap = 0;
  101. double maxoffset = 0.0;
  102. // aplptr ap;
  103. int is_launched = FALSE;
  104. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  105. fprintf(stdout,"%s\n",cdp_version);
  106. fflush(stdout);
  107. return 0;
  108. }
  109. /* CHECK FOR SOUNDLOOM */
  110. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  111. sloom = 0;
  112. sloombatch = 1;
  113. }
  114. if(sflinit("cdp")){
  115. sfperror("cdp: initialisation\n");
  116. return(FAILED);
  117. }
  118. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  119. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  120. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  121. return(FAILED);
  122. }
  123. if(!sloom) {
  124. if(argc == 1) {
  125. usage1();
  126. return(FAILED);
  127. } else if(argc == 2) {
  128. usage2(argv[1]);
  129. return(FAILED);
  130. }
  131. }
  132. if(!sloom) {
  133. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  134. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  135. return(FAILED);
  136. }
  137. cmdline = argv;
  138. cmdlinecnt = argc;
  139. if((get_the_process_no(argv[0],dz))<0)
  140. return(FAILED);
  141. cmdline++;
  142. cmdlinecnt--;
  143. dz->maxmode = 0;
  144. // setup_particular_application =
  145. if((exit_status = setup_phasor_application(dz))<0) {
  146. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  147. return(FAILED);
  148. }
  149. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  150. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  151. return(FAILED);
  152. }
  153. } else {
  154. //parse_TK_data() =
  155. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  156. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  157. return(exit_status);
  158. }
  159. }
  160. // ap = dz->application;
  161. // parse_infile_and_hone_type() =
  162. if((exit_status = parse_infile_and_check_type(cmdline,dz))<0) {
  163. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  164. return(FAILED);
  165. }
  166. // setup_param_ranges_and_defaults() =
  167. if((exit_status = setup_phasor_param_ranges_and_defaults(dz))<0) {
  168. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  169. return(FAILED);
  170. }
  171. // open_first_infile CDP LIB
  172. if((exit_status = open_first_infile(cmdline[0],dz))<0) {
  173. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  174. return(FAILED);
  175. }
  176. cmdlinecnt--;
  177. cmdline++;
  178. dz->duration = (double)dz->insams[0]/(double)dz->infile->srate;
  179. // handle_extra_infiles() : redundant
  180. // handle_outfile() =
  181. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,dz))<0) {
  182. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  183. return(FAILED);
  184. }
  185. // handle_formants() redundant
  186. // handle_formant_quiksearch() redundant
  187. // handle_special_data() redundant
  188. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  189. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  190. return(FAILED);
  191. }
  192. // check_param_validity_and_consistency....
  193. if((exit_status = check_phasor_param_validity_and_consistency(&maxoffset,dz))<0) {
  194. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  195. return(FAILED);
  196. }
  197. if((exit_status = open_the_outfile(dz))<0) {
  198. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  199. return(FAILED);
  200. }
  201. if((exit_status = create_phaseshift_and_outchan_data_arrays(&maxshiftslen,dz))<0) {
  202. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  203. return(FAILED);
  204. }
  205. is_launched = TRUE;
  206. dz->bufcnt = 3;
  207. if((dz->sampbuf = (float **)malloc(sizeof(float *) * (dz->bufcnt+1)))==NULL) {
  208. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffers.\n");
  209. return(MEMORY_ERROR);
  210. }
  211. if((dz->sbufptr = (float **)malloc(sizeof(float *) * dz->bufcnt))==NULL) {
  212. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffer pointers.\n");
  213. return(MEMORY_ERROR);
  214. }
  215. for(n = 0;n <dz->bufcnt; n++)
  216. dz->sampbuf[n] = dz->sbufptr[n] = (float *)0;
  217. dz->sampbuf[n] = (float *)0;
  218. if((exit_status = create_phasor_sndbufs(maxshiftslen,maxoffset,&offsetwrap,dz))<0) {
  219. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  220. return(FAILED);
  221. }
  222. //param_preprocess() redundant
  223. //spec_process_file =
  224. if((exit_status = phasor(offsetwrap,dz))<0) {
  225. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  226. return(FAILED);
  227. }
  228. if((exit_status = complete_output(dz))<0) { // CDP LIB
  229. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  230. return(FAILED);
  231. }
  232. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  233. free(dz);
  234. return(SUCCEEDED);
  235. }
  236. /**********************************************
  237. REPLACED CDP LIB FUNCTIONS
  238. **********************************************/
  239. /****************************** SET_PARAM_DATA *********************************/
  240. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  241. {
  242. ap->special_data = (char)special_data;
  243. ap->param_cnt = (char)paramcnt;
  244. ap->max_param_cnt = (char)maxparamcnt;
  245. if(ap->max_param_cnt>0) {
  246. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  247. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  248. return(MEMORY_ERROR);
  249. }
  250. strcpy(ap->param_list,paramlist);
  251. }
  252. return(FINISHED);
  253. }
  254. /****************************** SET_VFLGS *********************************/
  255. int set_vflgs
  256. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  257. {
  258. ap->option_cnt = (char) optcnt; /*RWD added cast */
  259. if(optcnt) {
  260. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  261. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  262. return(MEMORY_ERROR);
  263. }
  264. strcpy(ap->option_list,optlist);
  265. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  266. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  267. return(MEMORY_ERROR);
  268. }
  269. strcpy(ap->option_flags,optflags);
  270. }
  271. ap->vflag_cnt = (char) vflagcnt;
  272. ap->variant_param_cnt = (char) vparamcnt;
  273. if(vflagcnt) {
  274. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  275. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  276. return(MEMORY_ERROR);
  277. }
  278. strcpy(ap->variant_list,varlist);
  279. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  280. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  281. return(MEMORY_ERROR);
  282. }
  283. strcpy(ap->variant_flags,varflags);
  284. }
  285. return(FINISHED);
  286. }
  287. /***************************** APPLICATION_INIT **************************/
  288. int application_init(dataptr dz)
  289. {
  290. int exit_status;
  291. int storage_cnt;
  292. int tipc, brkcnt;
  293. aplptr ap = dz->application;
  294. if(ap->vflag_cnt>0)
  295. initialise_vflags(dz);
  296. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  297. ap->total_input_param_cnt = (char)tipc;
  298. if(tipc>0) {
  299. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  300. return(exit_status);
  301. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  302. return(exit_status);
  303. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  304. return(exit_status);
  305. }
  306. brkcnt = tipc;
  307. //THERE ARE NO INPUTFILE brktables USED IN THIS PROCESS
  308. if(brkcnt>0) {
  309. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  310. return(exit_status);
  311. }
  312. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  313. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  314. return(exit_status);
  315. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  316. return(exit_status);
  317. }
  318. if((exit_status = mark_parameter_types(dz,ap))<0)
  319. return(exit_status);
  320. // establish_infile_constants() replaced by
  321. dz->infilecnt = 1;
  322. //establish_bufptrs_and_extra_buffers():
  323. return(FINISHED);
  324. }
  325. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  326. /* RWD mallo changed to calloc; helps debug verison run as release! */
  327. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  328. {
  329. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  330. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  331. return(MEMORY_ERROR);
  332. }
  333. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  334. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  335. return(MEMORY_ERROR);
  336. }
  337. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  338. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  339. return(MEMORY_ERROR);
  340. }
  341. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  342. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  343. return(MEMORY_ERROR);
  344. }
  345. return(FINISHED);
  346. }
  347. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  348. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  349. {
  350. int n;
  351. for(n=0;n<storage_cnt;n++) {
  352. dz->is_int[n] = (char)0;
  353. dz->no_brk[n] = (char)0;
  354. }
  355. return(FINISHED);
  356. }
  357. /***************************** MARK_PARAMETER_TYPES **************************/
  358. int mark_parameter_types(dataptr dz,aplptr ap)
  359. {
  360. int n, m; /* PARAMS */
  361. for(n=0;n<ap->max_param_cnt;n++) {
  362. switch(ap->param_list[n]) {
  363. case('0'): break; /* dz->is_active[n] = 0 is default */
  364. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  365. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  366. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  367. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  368. default:
  369. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  370. return(PROGRAM_ERROR);
  371. }
  372. } /* OPTIONS */
  373. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  374. switch(ap->option_list[n]) {
  375. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  376. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  377. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  378. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  379. default:
  380. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  381. return(PROGRAM_ERROR);
  382. }
  383. } /* VARIANTS */
  384. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  385. switch(ap->variant_list[n]) {
  386. case('0'): break;
  387. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  388. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  389. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  390. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  391. default:
  392. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  393. return(PROGRAM_ERROR);
  394. }
  395. } /* INTERNAL */
  396. for(n=0,
  397. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  398. switch(ap->internal_param_list[n]) {
  399. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  400. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  401. case('d'): dz->no_brk[m] = (char)1; break;
  402. default:
  403. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  404. return(PROGRAM_ERROR);
  405. }
  406. }
  407. return(FINISHED);
  408. }
  409. /************************ HANDLE_THE_OUTFILE *********************/
  410. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz)
  411. {
  412. char *filename = (*cmdline)[0];
  413. if(filename[0]=='-' && filename[1]=='f') {
  414. dz->floatsam_output = 1;
  415. dz->true_outfile_stype = SAMP_FLOAT;
  416. filename+= 2;
  417. }
  418. if(!sloom) {
  419. if(file_has_invalid_startchar(filename) || value_is_numeric(filename)) {
  420. sprintf(errstr,"Outfile name %s has invalid start character(s) or looks too much like a number.\n",filename);
  421. return(DATA_ERROR);
  422. }
  423. }
  424. strcpy(dz->outfilename,filename);
  425. (*cmdline)++;
  426. (*cmdlinecnt)--;
  427. return(FINISHED);
  428. }
  429. /************************ OPEN_THE_OUTFILE *********************/
  430. int open_the_outfile(dataptr dz)
  431. {
  432. int exit_status, origchans;
  433. origchans = dz->infile->channels;
  434. dz->infile->channels = dz->iparam[PHASOR_OCHANS];
  435. if((exit_status = create_sized_outfile(dz->outfilename,dz))<0)
  436. return(exit_status);
  437. dz->infile->channels = origchans;
  438. dz->outfile->channels = dz->iparam[PHASOR_OCHANS];
  439. return(FINISHED);
  440. }
  441. /***************************** ESTABLISH_APPLICATION **************************/
  442. int establish_application(dataptr dz)
  443. {
  444. aplptr ap;
  445. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  446. sprintf(errstr,"establish_application()\n");
  447. return(MEMORY_ERROR);
  448. }
  449. ap = dz->application;
  450. memset((char *)ap,0,sizeof(struct applic));
  451. return(FINISHED);
  452. }
  453. /************************* INITIALISE_VFLAGS *************************/
  454. int initialise_vflags(dataptr dz)
  455. {
  456. int n;
  457. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  458. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  459. return(MEMORY_ERROR);
  460. }
  461. for(n=0;n<dz->application->vflag_cnt;n++)
  462. dz->vflag[n] = FALSE;
  463. return FINISHED;
  464. }
  465. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  466. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  467. {
  468. int n;
  469. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  470. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  471. return(MEMORY_ERROR);
  472. }
  473. for(n=0;n<tipc;n++)
  474. ap->default_val[n] = 0.0;
  475. return(FINISHED);
  476. }
  477. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  478. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  479. {
  480. int n;
  481. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  482. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  483. return(MEMORY_ERROR);
  484. }
  485. for(n=0;n<tipc;n++)
  486. dz->is_active[n] = (char)0;
  487. return(FINISHED);
  488. }
  489. /************************* SETUP_PHASOR_APPLICATION *******************/
  490. int setup_phasor_application(dataptr dz)
  491. {
  492. int exit_status;
  493. aplptr ap;
  494. if((exit_status = establish_application(dz))<0) // GLOBAL
  495. return(FAILED);
  496. ap = dz->application;
  497. // SEE parstruct FOR EXPLANATION of next 2 functions
  498. if((exit_status = set_param_data(ap,0 ,4,4,"iDDi"))<0)
  499. return(FAILED);
  500. if((exit_status = set_vflgs(ap,"o",1,"d","se",2,0,"00"))<0)
  501. return(FAILED);
  502. // set_legal_infile_structure -->
  503. dz->has_otherfile = FALSE;
  504. // assign_process_logic -->
  505. dz->input_data_type = SNDFILES_ONLY;
  506. dz->process_type = UNEQUAL_SNDFILE;
  507. dz->outfiletype = SNDFILE_OUT;
  508. return application_init(dz); //GLOBAL
  509. }
  510. /************************* PARSE_INFILE_AND_CHECK_TYPE *******************/
  511. int parse_infile_and_check_type(char **cmdline,dataptr dz)
  512. {
  513. int exit_status;
  514. infileptr infile_info;
  515. if(!sloom) {
  516. if((infile_info = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  517. sprintf(errstr,"INSUFFICIENT MEMORY for infile structure to test file data.");
  518. return(MEMORY_ERROR);
  519. } else if((exit_status = cdparse(cmdline[0],infile_info))<0) {
  520. sprintf(errstr,"Failed to parse input file %s\n",cmdline[0]);
  521. return(PROGRAM_ERROR);
  522. } else if(infile_info->filetype != SNDFILE) {
  523. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  524. return(DATA_ERROR);
  525. } else if(infile_info->channels != 1) {
  526. sprintf(errstr,"File %s is not of correct type (must be mono)\n",cmdline[0]);
  527. return(DATA_ERROR);
  528. } else if((exit_status = copy_parse_info_to_main_structure(infile_info,dz))<0) {
  529. sprintf(errstr,"Failed to copy file parsing information\n");
  530. return(PROGRAM_ERROR);
  531. }
  532. free(infile_info);
  533. }
  534. return(FINISHED);
  535. }
  536. /************************* SETUP_GATE_PARAM_RANGES_AND_DEFAULTS *******************/
  537. int setup_phasor_param_ranges_and_defaults(dataptr dz)
  538. {
  539. int exit_status;
  540. aplptr ap = dz->application;
  541. // set_param_ranges()
  542. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  543. // NB total_input_param_cnt is > 0 !!!
  544. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  545. return(FAILED);
  546. // get_param_ranges()
  547. ap->lo[PHASOR_STREAMS] = 2;
  548. ap->hi[PHASOR_STREAMS] = 8;
  549. ap->default_val[PHASOR_STREAMS] = 2;
  550. ap->lo[PHASOR_FRQ] = .01;
  551. ap->hi[PHASOR_FRQ] = 100;
  552. ap->default_val[PHASOR_FRQ] = 1;
  553. ap->lo[PHASOR_SHIFT] = 0;
  554. ap->hi[PHASOR_SHIFT] = 12;
  555. ap->default_val[PHASOR_SHIFT] = .5;
  556. ap->lo[PHASOR_OCHANS] = 1;
  557. ap->hi[PHASOR_OCHANS] = 8;
  558. ap->default_val[PHASOR_OCHANS] = 1;
  559. ap->lo[PHASOR_OFFSET] = 0;
  560. ap->hi[PHASOR_OFFSET] = 500;
  561. ap->default_val[PHASOR_OFFSET] = 0;
  562. dz->maxmode = 0;
  563. if(!sloom)
  564. put_default_vals_in_all_params(dz);
  565. return(FINISHED);
  566. }
  567. /********************************* PARSE_SLOOM_DATA *********************************/
  568. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  569. {
  570. int exit_status;
  571. int cnt = 1, infilecnt;
  572. int filesize, insams, inbrksize;
  573. double dummy;
  574. int true_cnt = 0;
  575. // aplptr ap;
  576. while(cnt<=PRE_CMDLINE_DATACNT) {
  577. if(cnt > argc) {
  578. sprintf(errstr,"Insufficient data sent from TK\n");
  579. return(DATA_ERROR);
  580. }
  581. switch(cnt) {
  582. case(1):
  583. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  584. sprintf(errstr,"Cannot read process no. sent from TK\n");
  585. return(DATA_ERROR);
  586. }
  587. break;
  588. case(2):
  589. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  590. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  591. return(DATA_ERROR);
  592. }
  593. if(dz->mode > 0)
  594. dz->mode--;
  595. //setup_particular_application() =
  596. if((exit_status = setup_phasor_application(dz))<0)
  597. return(exit_status);
  598. // ap = dz->application;
  599. break;
  600. case(3):
  601. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  602. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  603. return(DATA_ERROR);
  604. }
  605. if(infilecnt < 1) {
  606. true_cnt = cnt + 1;
  607. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  608. }
  609. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  610. return(exit_status);
  611. break;
  612. case(INPUT_FILETYPE+4):
  613. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  614. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  615. return(DATA_ERROR);
  616. }
  617. break;
  618. case(INPUT_FILESIZE+4):
  619. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  620. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  621. return(DATA_ERROR);
  622. }
  623. dz->insams[0] = filesize;
  624. break;
  625. case(INPUT_INSAMS+4):
  626. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  627. sprintf(errstr,"Cannot read insams sent from TK\n");
  628. return(DATA_ERROR);
  629. }
  630. dz->insams[0] = insams;
  631. break;
  632. case(INPUT_SRATE+4):
  633. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  634. sprintf(errstr,"Cannot read srate sent from TK\n");
  635. return(DATA_ERROR);
  636. }
  637. break;
  638. case(INPUT_CHANNELS+4):
  639. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  640. sprintf(errstr,"Cannot read channels sent from TK\n");
  641. return(DATA_ERROR);
  642. }
  643. break;
  644. case(INPUT_STYPE+4):
  645. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  646. sprintf(errstr,"Cannot read stype sent from TK\n");
  647. return(DATA_ERROR);
  648. }
  649. break;
  650. case(INPUT_ORIGSTYPE+4):
  651. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  652. sprintf(errstr,"Cannot read origstype sent from TK\n");
  653. return(DATA_ERROR);
  654. }
  655. break;
  656. case(INPUT_ORIGRATE+4):
  657. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  658. sprintf(errstr,"Cannot read origrate sent from TK\n");
  659. return(DATA_ERROR);
  660. }
  661. break;
  662. case(INPUT_MLEN+4):
  663. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  664. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  665. return(DATA_ERROR);
  666. }
  667. break;
  668. case(INPUT_DFAC+4):
  669. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  670. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  671. return(DATA_ERROR);
  672. }
  673. break;
  674. case(INPUT_ORIGCHANS+4):
  675. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  676. sprintf(errstr,"Cannot read origchans sent from TK\n");
  677. return(DATA_ERROR);
  678. }
  679. break;
  680. case(INPUT_SPECENVCNT+4):
  681. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  682. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  683. return(DATA_ERROR);
  684. }
  685. dz->specenvcnt = dz->infile->specenvcnt;
  686. break;
  687. case(INPUT_WANTED+4):
  688. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  689. sprintf(errstr,"Cannot read wanted sent from TK\n");
  690. return(DATA_ERROR);
  691. }
  692. break;
  693. case(INPUT_WLENGTH+4):
  694. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  695. sprintf(errstr,"Cannot read wlength sent from TK\n");
  696. return(DATA_ERROR);
  697. }
  698. break;
  699. case(INPUT_OUT_CHANS+4):
  700. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  701. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  702. return(DATA_ERROR);
  703. }
  704. break;
  705. /* RWD these chanegs to samps - tk will have to deal with that! */
  706. case(INPUT_DESCRIPTOR_BYTES+4):
  707. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  708. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  709. return(DATA_ERROR);
  710. }
  711. break;
  712. case(INPUT_IS_TRANSPOS+4):
  713. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  714. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  715. return(DATA_ERROR);
  716. }
  717. break;
  718. case(INPUT_COULD_BE_TRANSPOS+4):
  719. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  720. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  721. return(DATA_ERROR);
  722. }
  723. break;
  724. case(INPUT_COULD_BE_PITCH+4):
  725. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  726. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  727. return(DATA_ERROR);
  728. }
  729. break;
  730. case(INPUT_DIFFERENT_SRATES+4):
  731. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  732. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  733. return(DATA_ERROR);
  734. }
  735. break;
  736. case(INPUT_DUPLICATE_SNDS+4):
  737. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  738. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  739. return(DATA_ERROR);
  740. }
  741. break;
  742. case(INPUT_BRKSIZE+4):
  743. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  744. sprintf(errstr,"Cannot read brksize sent from TK\n");
  745. return(DATA_ERROR);
  746. }
  747. if(inbrksize > 0) {
  748. switch(dz->input_data_type) {
  749. case(WORDLIST_ONLY):
  750. break;
  751. case(PITCH_AND_PITCH):
  752. case(PITCH_AND_TRANSPOS):
  753. case(TRANSPOS_AND_TRANSPOS):
  754. dz->tempsize = inbrksize;
  755. break;
  756. case(BRKFILES_ONLY):
  757. case(UNRANGED_BRKFILE_ONLY):
  758. case(DB_BRKFILES_ONLY):
  759. case(ALL_FILES):
  760. case(ANY_NUMBER_OF_ANY_FILES):
  761. if(dz->extrabrkno < 0) {
  762. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  763. return(DATA_ERROR);
  764. }
  765. if(dz->brksize == NULL) {
  766. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  767. return(PROGRAM_ERROR);
  768. }
  769. dz->brksize[dz->extrabrkno] = inbrksize;
  770. break;
  771. default:
  772. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  773. dz->input_data_type);
  774. return(PROGRAM_ERROR);
  775. }
  776. break;
  777. }
  778. break;
  779. case(INPUT_NUMSIZE+4):
  780. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  781. sprintf(errstr,"Cannot read numsize sent from TK\n");
  782. return(DATA_ERROR);
  783. }
  784. break;
  785. case(INPUT_LINECNT+4):
  786. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  787. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  788. return(DATA_ERROR);
  789. }
  790. break;
  791. case(INPUT_ALL_WORDS+4):
  792. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  793. sprintf(errstr,"Cannot read all_words sent from TK\n");
  794. return(DATA_ERROR);
  795. }
  796. break;
  797. case(INPUT_ARATE+4):
  798. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  799. sprintf(errstr,"Cannot read arate sent from TK\n");
  800. return(DATA_ERROR);
  801. }
  802. break;
  803. case(INPUT_FRAMETIME+4):
  804. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  805. sprintf(errstr,"Cannot read frametime sent from TK\n");
  806. return(DATA_ERROR);
  807. }
  808. dz->frametime = (float)dummy;
  809. break;
  810. case(INPUT_WINDOW_SIZE+4):
  811. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  812. sprintf(errstr,"Cannot read window_size sent from TK\n");
  813. return(DATA_ERROR);
  814. }
  815. break;
  816. case(INPUT_NYQUIST+4):
  817. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  818. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  819. return(DATA_ERROR);
  820. }
  821. break;
  822. case(INPUT_DURATION+4):
  823. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  824. sprintf(errstr,"Cannot read duration sent from TK\n");
  825. return(DATA_ERROR);
  826. }
  827. break;
  828. case(INPUT_MINBRK+4):
  829. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  830. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  831. return(DATA_ERROR);
  832. }
  833. break;
  834. case(INPUT_MAXBRK+4):
  835. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  836. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  837. return(DATA_ERROR);
  838. }
  839. break;
  840. case(INPUT_MINNUM+4):
  841. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  842. sprintf(errstr,"Cannot read minnum sent from TK\n");
  843. return(DATA_ERROR);
  844. }
  845. break;
  846. case(INPUT_MAXNUM+4):
  847. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  848. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  849. return(DATA_ERROR);
  850. }
  851. break;
  852. default:
  853. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  854. return(PROGRAM_ERROR);
  855. }
  856. cnt++;
  857. }
  858. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  859. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  860. return(DATA_ERROR);
  861. }
  862. if(true_cnt)
  863. cnt = true_cnt;
  864. *cmdlinecnt = 0;
  865. while(cnt < argc) {
  866. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  867. return(exit_status);
  868. cnt++;
  869. }
  870. return(FINISHED);
  871. }
  872. /********************************* GET_TK_CMDLINE_WORD *********************************/
  873. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  874. {
  875. if(*cmdlinecnt==0) {
  876. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  877. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  878. return(MEMORY_ERROR);
  879. }
  880. } else {
  881. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  882. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  883. return(MEMORY_ERROR);
  884. }
  885. }
  886. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  887. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  888. return(MEMORY_ERROR);
  889. }
  890. strcpy((*cmdline)[*cmdlinecnt],q);
  891. (*cmdlinecnt)++;
  892. return(FINISHED);
  893. }
  894. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  895. int assign_file_data_storage(int infilecnt,dataptr dz)
  896. {
  897. int exit_status;
  898. int no_sndfile_system_files = FALSE;
  899. dz->infilecnt = infilecnt;
  900. if((exit_status = allocate_filespace(dz))<0)
  901. return(exit_status);
  902. if(no_sndfile_system_files)
  903. dz->infilecnt = 0;
  904. return(FINISHED);
  905. }
  906. /************************* redundant functions: to ensure libs compile OK *******************/
  907. int assign_process_logic(dataptr dz)
  908. {
  909. return(FINISHED);
  910. }
  911. void set_legal_infile_structure(dataptr dz)
  912. {}
  913. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  914. {
  915. return(FINISHED);
  916. }
  917. int setup_internal_arrays_and_array_pointers(dataptr dz)
  918. {
  919. return(FINISHED);
  920. }
  921. int establish_bufptrs_and_extra_buffers(dataptr dz)
  922. {
  923. return(FINISHED);
  924. }
  925. int read_special_data(char *str,dataptr dz)
  926. {
  927. return(FINISHED);
  928. }
  929. int inner_loop
  930. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  931. {
  932. return(FINISHED);
  933. }
  934. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  935. {
  936. return(FINISHED);
  937. }
  938. /******************************** USAGE1 ********************************/
  939. int usage1(void)
  940. {
  941. usage2("phasor");
  942. return(USAGE_ONLY);
  943. }
  944. /**************************** CHECK_GATE_PARAM_VALIDITY_AND_CONSISTENCY *****************************/
  945. int check_phasor_param_validity_and_consistency(double *maxoffset,dataptr dz)
  946. {
  947. int exit_status;
  948. if(dz->iparam[PHASOR_OCHANS] > dz->iparam[PHASOR_STREAMS]) {
  949. sprintf(errstr,"Number of output channels exceeds number of streams.\n");
  950. return(DATA_ERROR);
  951. }
  952. if(dz->brksize[PHASOR_OFFSET]) {
  953. if((exit_status = get_maxvalue_in_brktable(maxoffset,PHASOR_OFFSET,dz))<0)
  954. return exit_status;
  955. } else
  956. *maxoffset = dz->param[PHASOR_OFFSET];
  957. if(dz->vflag[0] && (dz->iparam[PHASOR_OCHANS] <= 2)) {
  958. sprintf(errstr,"NO SOUND-SURROUND POSSIBLE WITH %d OUTPUT CHANNELS\n",dz->iparam[PHASOR_OCHANS]);
  959. return DATA_ERROR;
  960. }
  961. return FINISHED;
  962. }
  963. /********************************************************************************************/
  964. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  965. {
  966. if(!strcmp(prog_identifier_from_cmdline,"phasor")) dz->process = PHASOR;
  967. else {
  968. fprintf(stderr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  969. return(USAGE_ONLY);
  970. }
  971. return(FINISHED);
  972. }
  973. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  974. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  975. {
  976. int n;
  977. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  978. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  979. return(MEMORY_ERROR);
  980. }
  981. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  982. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  983. return(MEMORY_ERROR);
  984. }
  985. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  986. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  987. return(MEMORY_ERROR);
  988. }
  989. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  990. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  991. return(MEMORY_ERROR);
  992. }
  993. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  994. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  995. return(MEMORY_ERROR);
  996. }
  997. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  998. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  999. return(MEMORY_ERROR);
  1000. }
  1001. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1002. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  1003. return(MEMORY_ERROR);
  1004. }
  1005. for(n=0;n<brkcnt;n++) {
  1006. dz->brk[n] = NULL;
  1007. dz->brkptr[n] = NULL;
  1008. dz->brkinit[n] = 0;
  1009. dz->brksize[n] = 0;
  1010. }
  1011. return(FINISHED);
  1012. }
  1013. /******************************** USAGE2 ********************************/
  1014. int usage2(char *str)
  1015. {
  1016. if(!strcmp(str,"phasor")) {
  1017. fprintf(stderr,
  1018. "USAGE:\n"
  1019. "phasor phasor infile outfile streams phasfrq shift ochans [-ooffset] [-s] [-e]\n"
  1020. "\n"
  1021. "Introduce phasing into signal : Takes a MONO input file.\n"
  1022. "\n"
  1023. "STREAMS Number of output streams that phase-interact (Range 2 - 8)\n"
  1024. "PHASFRQ Frequency of packets (phase shifts forward then back in a single packet).\n"
  1025. "SHIFT Maximum phaseshift with packet: (Range 0 - 12 semitones).\n"
  1026. "OCHANS Number of output channels (not greater than number of streams).\n"
  1027. "OFFSET The streams may be time-offset from one another..\n"
  1028. " \"Offset\" is time-offset of the most-offset stream (Range 0 - 500 mS).\n"
  1029. " The other streams are offset by intermediate amounts.\n"
  1030. "\n"
  1031. "-s Output chans (lspkrs) encircle audience : only with more than 2 ochans.\n"
  1032. "-e Prints warnings re rounding-errors in calculating time-shifted streams.\n"
  1033. "\n"
  1034. "\"shift\" and \"phasfrq\" can vary through time,\n"
  1035. "but extreme phasfrq changes or reversals will produce anomalous output.\n"
  1036. "\n");
  1037. } else
  1038. fprintf(stdout,"Unknown option '%s'\n",str);
  1039. return(USAGE_ONLY);
  1040. }
  1041. int usage3(char *str1,char *str2)
  1042. {
  1043. fprintf(stderr,"Insufficient parameters on command line.\n");
  1044. return(USAGE_ONLY);
  1045. }
  1046. /******************************** CREATE_PHASESHIFT_AND_OUTCHAN_DATA_ARRAYS ********************************/
  1047. int create_phaseshift_and_outchan_data_arrays(int *maxshiftslen, dataptr dz)
  1048. {
  1049. int exit_status, n, m, chan;
  1050. double time = 0, srate = (double)dz->infile->srate, leftgain = 0.0, rightgain = 0.0, chanpos, pos;
  1051. *maxshiftslen = 0;
  1052. while(time < dz->duration) {
  1053. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  1054. return exit_status;
  1055. *maxshiftslen = max(*maxshiftslen,(int)ceil(srate/dz->param[PHASOR_FRQ]));
  1056. time += 1.0/dz->param[PHASOR_FRQ];
  1057. }
  1058. while(((*maxshiftslen)/4) * 4 != *maxshiftslen)
  1059. (*maxshiftslen)++; // phaseshift arrays must have a multiple-of-4 entries
  1060. *maxshiftslen += WRAP; // Allow for wraparound point and accumulation (of samp-pointer position) errors
  1061. dz->outchinfo = dz->iparam[PHASOR_STREAMS] - 1;
  1062. if((dz->parray = (double **)malloc((dz->outchinfo + dz->iparam[PHASOR_STREAMS]) * sizeof(double *)))==NULL) {
  1063. sprintf(errstr,"INSUFFICIENT MEMORY to store phaseshift data arrays.\n");
  1064. return(MEMORY_ERROR);
  1065. }
  1066. for(n = 0; n < dz->outchinfo; n++) {
  1067. if((dz->parray[n] = (double *)malloc(((*maxshiftslen) + SAFETY) * sizeof(double)))==NULL) {
  1068. sprintf(errstr,"INSUFFICIENT MEMORY to store phaseshift data, stream %d.\n",n+1);
  1069. return(MEMORY_ERROR);
  1070. }
  1071. }
  1072. for(n = dz->outchinfo; n < dz->outchinfo + dz->iparam[PHASOR_STREAMS]; n++) {
  1073. if((dz->parray[n] = (double *)malloc(4 * sizeof(double)))==NULL) {
  1074. sprintf(errstr,"INSUFFICIENT MEMORY to store phaseshift data, stream %d.\n",n+1);
  1075. return(MEMORY_ERROR);
  1076. }
  1077. }
  1078. if(dz->iparam[PHASOR_STREAMS] == dz->iparam[PHASOR_OCHANS]) {
  1079. for(n=0,m = dz->outchinfo;n < dz->iparam[PHASOR_OCHANS]; n++,m++) {
  1080. dz->parray[m][0] = (double)n;
  1081. dz->parray[m][1] = 1.0;
  1082. dz->parray[m][2] = (double)((n+1)%dz->iparam[PHASOR_OCHANS]);
  1083. dz->parray[m][3] = 0.0;
  1084. }
  1085. } else {
  1086. if(dz->vflag[0]) { /* Sound surround, 5 streams on 4 chans are positioned at 0 4/5 1+3/5 2+2/5 3+1/5 */
  1087. for(n=0,m = dz->outchinfo;n < dz->iparam[PHASOR_STREAMS]; n++,m++) {
  1088. chanpos = ((double)n/(double)dz->iparam[PHASOR_STREAMS]) * (double)dz->iparam[PHASOR_OCHANS]; // e.g. 3.7
  1089. chan = (int)floor(chanpos); // 3
  1090. pos = chanpos - (double)chan; // 0.7 in range 0 to 1
  1091. pos = (2.0 * pos) - 1.0; // 0.4 in range -1 to 0
  1092. pancalc(pos,&leftgain,&rightgain);
  1093. dz->parray[m][0] = (double)chan;
  1094. dz->parray[m][1] = leftgain;
  1095. dz->parray[m][2] = (double)((chan+1)%dz->iparam[PHASOR_OCHANS]);
  1096. dz->parray[m][3] = rightgain;
  1097. }
  1098. } else { /* Linear array, 5 streams on 4 chans are positioned at 0 3/4 1+1/2 2+3/4 3 */
  1099. for(n=0,m = dz->outchinfo;n < dz->iparam[PHASOR_STREAMS]; n++,m++) {
  1100. chanpos = (double)n/(double)(dz->iparam[PHASOR_STREAMS] - 1) * (double)(dz->iparam[PHASOR_OCHANS] - 1);
  1101. chan = (int)floor(chanpos);
  1102. pos = chanpos - (double)chan;
  1103. pos = (2.0 * pos) - 1.0;
  1104. pancalc(pos,&leftgain,&rightgain);
  1105. dz->parray[m][0] = (double)chan;
  1106. dz->parray[m][1] = leftgain;
  1107. dz->parray[m][2] = (double)((chan+1)%dz->iparam[PHASOR_OCHANS]);
  1108. dz->parray[m][3] = rightgain;
  1109. }
  1110. }
  1111. }
  1112. return FINISHED;
  1113. }
  1114. /******************************** CREATE_PHASOR_SNDBUFS ********************************/
  1115. int create_phasor_sndbufs(int maxshiftslen,double maxoffset,int *offsetwrap,dataptr dz)
  1116. {
  1117. int bigbufsize, seccnt;
  1118. int framesize = F_SECSIZE;
  1119. double srate = (double)dz->infile->srate;
  1120. if(maxoffset > 0.0) { // Additional buffer space, if streams are offset from one another
  1121. dz->maxoffset = (int)ceil(maxoffset * MS_TO_SECS * srate);
  1122. *offsetwrap = dz->maxoffset * dz->iparam[PHASOR_OCHANS];
  1123. *offsetwrap += WRAP;
  1124. seccnt = (*offsetwrap)/framesize;
  1125. if(seccnt * framesize < *offsetwrap)
  1126. seccnt++;
  1127. *offsetwrap = seccnt * framesize;
  1128. }
  1129. seccnt = maxshiftslen/framesize;
  1130. if(seccnt * framesize < maxshiftslen)
  1131. seccnt++;
  1132. bigbufsize = seccnt * framesize;
  1133. dz->buflen = bigbufsize;
  1134. dz->ibuflen = dz->buflen; // Input buffer size
  1135. bigbufsize *= (1 + (3 * dz->iparam[PHASOR_OCHANS])); // 1 mono and 1 multichan (pbuf), + 1 dopuble-size outbuf
  1136. if(maxoffset > 0.0)
  1137. bigbufsize += 2 * *offsetwrap; // once for pbuf, and once for overflowbuf
  1138. if((dz->bigbuf = (float *)malloc(bigbufsize * sizeof(float))) == NULL) {
  1139. sprintf(errstr,"INSUFFICIENT MEMORY to create sound buffers.\n");
  1140. return(PROGRAM_ERROR);
  1141. }
  1142. dz->sbufptr[0] = dz->sampbuf[0] = dz->bigbuf;
  1143. dz->sbufptr[1] = dz->sampbuf[1] = dz->bigbuf + dz->buflen; // Input buffer (mono)
  1144. dz->buflen *= dz->iparam[PHASOR_OCHANS]; // Buflen used in calculation is size of multichan buffers
  1145. dz->sbufptr[2] = dz->sampbuf[2] = dz->sampbuf[1] + dz->buflen + *offsetwrap; // Packet buffer (multichan) + its possible overflow + offset-extension
  1146. dz->sampbuf[3] = dz->sampbuf[2] + dz->buflen + dz->buflen + *offsetwrap;// Output buffer (multichan) + overflow buffer + offset-extension to overflow
  1147. return FINISHED;
  1148. }
  1149. /******************************** PHASOR ********************************/
  1150. int phasor(int offsetwrap,dataptr dz)
  1151. {
  1152. int exit_status, passno;
  1153. double time, normaliser = 1.0, maxsamp = 0.0;
  1154. float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[2];
  1155. int phaseshiftcnt, ibufpos, obufpos, n, origbuflen = 0, absolute_endofwrite = 0;
  1156. for(passno = 0; passno < 2; passno++) {
  1157. dz->total_samps_read = 0;
  1158. dz->samps_left = dz->insams[0];
  1159. time = 0.0;
  1160. ibufpos = 0;
  1161. obufpos = 0;
  1162. memset((char *)ibuf,0,dz->ibuflen * sizeof(float));
  1163. memset((char *)obuf,0,((dz->buflen * 2) + offsetwrap) * sizeof(float));
  1164. sndseekEx(dz->ifd[0],0,0);
  1165. origbuflen = dz->buflen;
  1166. dz->buflen = dz->ibuflen;
  1167. if((exit_status = read_samps(ibuf,dz))<0)
  1168. return(exit_status);
  1169. dz->buflen = origbuflen;
  1170. while(time < dz->duration) {
  1171. if((exit_status = calculate_phase_shifts(time,&phaseshiftcnt,dz))<0)
  1172. return exit_status;
  1173. if((exit_status = calculate_streams(time,phaseshiftcnt,&obufpos,&ibufpos,passno,normaliser,&maxsamp,offsetwrap,&absolute_endofwrite,dz))<0)
  1174. return exit_status;
  1175. if(exit_status == FINISHED)
  1176. break;
  1177. time += 1.0/dz->param[PHASOR_FRQ];
  1178. }
  1179. if(passno == 0) {
  1180. if(absolute_endofwrite > 0) {
  1181. for(n=0;n<absolute_endofwrite;n++)
  1182. maxsamp = max(maxsamp,fabs(obuf[n]));
  1183. }
  1184. if(maxsamp > MAXOUTLEVEL)
  1185. normaliser = MAXOUTLEVEL/maxsamp;
  1186. } else {
  1187. if(absolute_endofwrite > 0) {
  1188. for(n=0;n<absolute_endofwrite;n++)
  1189. obuf[n] = (float)(obuf[n] * normaliser);
  1190. if((exit_status = write_samps(obuf,absolute_endofwrite,dz))<0)
  1191. return(exit_status);
  1192. }
  1193. }
  1194. }
  1195. return FINISHED;
  1196. }
  1197. /******************************** CALCULATE_PHASE_SHIFTS ********************************/
  1198. int calculate_phase_shifts(double time, int *phaseshiftcnt, dataptr dz)
  1199. {
  1200. int exit_status;
  1201. double srate = (double)dz->infile->srate, maxphaseshift, minphaseshift, thismax, posoffset, sum, error;
  1202. double *sampincr;
  1203. int midway, quartway,/* threequartway,*/ n, k, j;
  1204. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  1205. return exit_status;
  1206. maxphaseshift = dz->param[PHASOR_SHIFT];
  1207. minphaseshift = maxphaseshift/(dz->iparam[PHASOR_STREAMS] - 1);
  1208. *phaseshiftcnt = (int)floor(srate/dz->param[PHASOR_FRQ]);
  1209. while((*phaseshiftcnt/4) * 4 != *phaseshiftcnt)
  1210. (*phaseshiftcnt)++; // phaseshift arrays must have a multiple-of-4 entries
  1211. midway = (*phaseshiftcnt)/2; // midpoint of arrays
  1212. quartway = midway/2;
  1213. // threequartway = midway + quartway;
  1214. for(n = 0; n < dz->iparam[PHASOR_STREAMS]-1;n++) { // Set max-shift for this stream
  1215. sum = 0.0;
  1216. thismax = min(maxphaseshift,(n+1) * minphaseshift);
  1217. thismax = thismax/SEMITONES_PER_OCTAVE; // Convert to octaves
  1218. posoffset = thismax/(double)quartway; // semitone-displacement per sample.
  1219. /* If 8 samps to midway, midway = 8, quartway = 4 : midway-2 = 6 */
  1220. sampincr = dz->parray[n]; /* */
  1221. for(k = 0; k < quartway; k++) /* Rising A/\B e.g. k=0 1 2 3 */
  1222. sampincr[k] = min((k+1) * posoffset,thismax); /* portion A / \ +1 +2 +3 +4 */
  1223. /* \C D/ j=6 5 4 */
  1224. for(k = 0,j = midway - 2; k < quartway-1; k++,j--) /* Falling \/ j=7 gets 0 */
  1225. sampincr[j] = sampincr[k]; /* portion B */
  1226. sampincr[midway-1] = 0.0;
  1227. for(k = 0,j = midway; k < midway; k++,j++) /* Falling & Rising portions C & D */
  1228. sampincr[j] = -sampincr[k]; /* Every +ve sampincr in A+B */
  1229. /* compensated for by equal -ve sampincr */
  1230. /* in C+D, so signals should resync! */
  1231. for(k=0;k < *phaseshiftcnt;k++)
  1232. sampincr[k] = pow(2.0,sampincr[k]); /* semitones-->frqratio = sampincr */
  1233. sum = 0.0;
  1234. for(k=0;k < *phaseshiftcnt;k++) /* check error in summing all increments */
  1235. sum += sampincr[k];
  1236. error = (sum - (double)*phaseshiftcnt)/(double)(*phaseshiftcnt);
  1237. for(k=0;k < *phaseshiftcnt;k++) /* adjust increments to eliminate error */
  1238. sampincr[k] -= error;
  1239. }
  1240. return FINISHED;
  1241. }
  1242. /******************************** CALCULATE_STREAMS ********************************/
  1243. int calculate_streams(double time,int phaseshiftcnt, int *obufpos, int *ibufpos, int passno, double normaliser, double *maxsamp, int offsetwrap, int *absolute_endofwrite, dataptr dz)
  1244. {
  1245. int exit_status;
  1246. float *ibuf = dz->sampbuf[0];
  1247. float *pbuf = dz->sampbuf[1];
  1248. float *obuf = dz->sampbuf[2];
  1249. double ibufposd, srate = (double)dz->infile->srate, ch1lev = 0.0, ch2lev = 0.0;
  1250. double loval, valdiff, timefrac, val, val1, val2;
  1251. double *outchan_info, *sampincr;
  1252. int n, origbuflen, offset[8], bufadjust, thisoffset, k, ibufpos_for_each_stream = 0, lopos, hipos, ovflow;
  1253. int pbufpos = 0, advance_to_next_write = 0, pbufpos1 = 0, pbufpos2 = 0, endibufpos = 0, xmaxoffset, position_of_next_write, samps_to_write, xobufpos;
  1254. int warning = 0, streamcnt = dz->iparam[PHASOR_STREAMS], ochan1, ochan2;
  1255. memset((char *)pbuf,0, (dz->buflen + offsetwrap) * sizeof(float));
  1256. if(*ibufpos + phaseshiftcnt + 1 >= dz->ibuflen) { // Ensure all of read will go into the input buffer
  1257. bufadjust = dz->ssampsread - *ibufpos;
  1258. sndseekEx(dz->ifd[0],dz->total_samps_read - bufadjust,0);
  1259. dz->total_samps_read -= bufadjust;
  1260. memset((char *)ibuf,0,dz->ibuflen * sizeof(float));
  1261. origbuflen = dz->buflen;
  1262. dz->buflen = dz->ibuflen; // input buffer size
  1263. if((exit_status = read_samps(ibuf,dz))<0)
  1264. return(exit_status);
  1265. dz->buflen = origbuflen; // Restore dz->buflen for calcs in output buffer
  1266. if(dz->ssampsread <= 0)
  1267. return FINISHED;
  1268. *ibufpos = 0;
  1269. }
  1270. /* CALCULATE ANY STREAM TIME-OFFSETS */
  1271. thisoffset = (int)round(dz->param[PHASOR_OFFSET] * MS_TO_SECS * srate); // With 4 streams, offsets go ...
  1272. offset[0] = 0; //
  1273. xmaxoffset = 0; // |----------------------------
  1274. for(k = 1; k < streamcnt-1;k++) { // | |----------------------------
  1275. offset[k] = (int)round(((double)k/(double)(streamcnt - 1)) * (double)thisoffset); // | | |----------------------------
  1276. xmaxoffset = max(xmaxoffset,offset[k]); // | | | |----------------------------
  1277. } // 0 1/3 2/3 thisoffset
  1278. offset[k] = thisoffset;
  1279. xmaxoffset = max(xmaxoffset,offset[k]);
  1280. for(k = 0; k < streamcnt; k++) {
  1281. if(k==0)
  1282. ibufpos_for_each_stream = *ibufpos; // Current read-position in input
  1283. else if(k==1) {
  1284. endibufpos = ibufpos_for_each_stream; // ibufpos_for_each_stream has advanced from initial ibufpos , while writing stream 0 :
  1285. // and now tells us where we've reached in the input buffer.
  1286. advance_to_next_write = pbufpos; // pbufpos has advanced from zero, while writing stream 0 :
  1287. // It now tells us how many samples to advance, in output-buf, for next set-of-streams to be written to output
  1288. }
  1289. pbufpos = offset[k] * dz->iparam[PHASOR_OCHANS]; // Initial time-offset of this stream (as a whole number of channel-groups), default is zero
  1290. ibufposd = (double)(*ibufpos); // Ditto as a floatval which can be fractionally incremented
  1291. outchan_info = dz->parray[dz->outchinfo + k]; // Output channel information for this stream
  1292. ochan1 = (int)round(outchan_info[0]);
  1293. ch1lev = outchan_info[1];
  1294. ochan2 = (int)round(outchan_info[2]);
  1295. ch2lev = outchan_info[3];
  1296. pbufpos1 = pbufpos + ochan1; // Actual start sample for this particular stream feeding particular output channel
  1297. pbufpos2 = pbufpos + ochan2; // Actual start sample for this particular stream feeding adjacent output channel
  1298. for(n = 0; n < phaseshiftcnt; n++) {
  1299. if(k==0) {
  1300. pbuf[pbufpos] = (float)(pbuf[pbufpos] + ibuf[ibufpos_for_each_stream]); // Stream 0 always goes entirely to channel 0
  1301. pbufpos += dz->iparam[PHASOR_OCHANS]; // Step to next output-channel-group
  1302. ibufpos_for_each_stream++; // Advance at normal rate in input
  1303. } else {
  1304. sampincr = dz->parray[k-1];
  1305. ibufposd += sampincr[n]; // Advance in input by timewarp value stored in array
  1306. lopos = (int)round(ibufposd);
  1307. if(lopos >= phaseshiftcnt) {
  1308. warning++;
  1309. lopos = phaseshiftcnt;
  1310. }
  1311. hipos = lopos + 1;
  1312. loval = ibuf[lopos];
  1313. valdiff = ibuf[hipos] - loval;
  1314. timefrac = ibufposd - (double)lopos;
  1315. val = loval + (valdiff * timefrac); // Value obtained by interpolating in input sound
  1316. val1 = val * ch1lev; // Distribute this between the 2 appropriate output channels
  1317. pbuf[pbufpos1] = (float)(pbuf[pbufpos1] + val1);
  1318. val2 = val * ch2lev;
  1319. pbuf[pbufpos2] = (float)(pbuf[pbufpos2] + val2);
  1320. pbufpos1 += dz->iparam[PHASOR_OCHANS]; // Step to appropriate-chan-positions in next output-channel-group
  1321. pbufpos2 += dz->iparam[PHASOR_OCHANS];
  1322. }
  1323. }
  1324. }
  1325. *ibufpos = endibufpos; // Reset final ibufpos - at end of loop through input samps.
  1326. position_of_next_write = *obufpos + advance_to_next_write; // Calculate position of NEXT write, from outbuf
  1327. // Calculate absolute end of current write, in outbuf
  1328. *absolute_endofwrite = position_of_next_write + (dz->iparam[PHASOR_OCHANS] * xmaxoffset);
  1329. ovflow = *absolute_endofwrite - dz->buflen;
  1330. if(ovflow >= dz->buflen + offsetwrap) { // check that any overflow of principal output buffer does not exceed length of overflow-buffer
  1331. sprintf(errstr,"Buffer size underestimated,\n");
  1332. return PROGRAM_ERROR;
  1333. }
  1334. // Write samples into the output buffer (even if they overflow), as far as absolute end of write
  1335. samps_to_write = *absolute_endofwrite - *obufpos;
  1336. xobufpos = *obufpos;
  1337. for(n = 0; n < samps_to_write; n++) {
  1338. obuf[xobufpos] = (float)(obuf[xobufpos] + pbuf[n]);
  1339. xobufpos++;
  1340. }
  1341. *obufpos = position_of_next_write; // Reset output buffer write position, ready for next pass
  1342. if(position_of_next_write >= dz->buflen) { // If no further samples will be added to the current buffer (because next write is beyond its end)
  1343. if(passno == 0) { // We can process-or-write the complete current buffer
  1344. for(n=0;n<dz->buflen;n++)
  1345. *maxsamp = max(*maxsamp,fabs(obuf[n]));
  1346. } else {
  1347. for(n=0;n<dz->buflen;n++)
  1348. obuf[n] = (float)(obuf[n] * normaliser);
  1349. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1350. return(exit_status);
  1351. }
  1352. memset((char *)obuf,0,dz->buflen * sizeof(float));
  1353. memcpy((char *)obuf,(char *)(obuf + dz->buflen), dz->buflen * sizeof(float)); // Wrap-around any overflow in output buffer.
  1354. memset((char *)(obuf + dz->buflen),0,dz->buflen * sizeof(float)); // re-zero the overflow buffer.
  1355. if(offsetwrap > 0) { // Wrap around any data in the offsetwrap extension of the overflow buffer
  1356. memcpy((char *)(obuf + dz->buflen),(char *)(obuf + (dz->buflen * 2)), offsetwrap * sizeof(float));
  1357. memset((char *)(obuf + (dz->buflen * 2)),0,offsetwrap * sizeof(float)); // re-zero the offsetwrap buffer.
  1358. }
  1359. *obufpos -= dz->buflen; // Reset outbuf pointer.
  1360. *absolute_endofwrite -= dz->buflen;
  1361. }
  1362. if(dz->vflag[1] && warning) {
  1363. fprintf(stdout,"WARNING: %d rounding errors at time %lf\n",warning,time);
  1364. fflush(stdout);
  1365. }
  1366. return CONTINUE;
  1367. }
  1368. /************************************ PANCALC *******************************/
  1369. void pancalc(double position,double *leftgain,double *rightgain)
  1370. {
  1371. int dirflag;
  1372. double temp;
  1373. double relpos;
  1374. double reldist, invsquare;
  1375. if(position < 0.0)
  1376. dirflag = SIGNAL_TO_LEFT; /* signal on left */
  1377. else
  1378. dirflag = SIGNAL_TO_RIGHT;
  1379. if(position < 0)
  1380. relpos = -position;
  1381. else
  1382. relpos = position;
  1383. if(relpos <= 1.0){ /* between the speakers */
  1384. temp = 1.0 + (relpos * relpos);
  1385. reldist = ROOT2 / sqrt(temp);
  1386. temp = (position + 1.0) / 2.0;
  1387. *rightgain = temp * reldist;
  1388. *leftgain = (1.0 - temp ) * reldist;
  1389. } else { /* outside the speakers */
  1390. temp = (relpos * relpos) + 1.0;
  1391. reldist = sqrt(temp) / ROOT2; /* relative distance to source */
  1392. invsquare = 1.0 / (reldist * reldist);
  1393. if(dirflag == SIGNAL_TO_LEFT){
  1394. *leftgain = invsquare;
  1395. *rightgain = 0.0;
  1396. } else { /* SIGNAL_TO_RIGHT */
  1397. *rightgain = invsquare;
  1398. *leftgain = 0;
  1399. }
  1400. }
  1401. }