frame.c 99 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342
  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. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <structures.h>
  24. #include <tkglobals.h>
  25. #include <pnames.h>
  26. #include <filetype.h>
  27. #include <processno.h>
  28. #include <modeno.h>
  29. #include <logic.h>
  30. #include <globcon.h>
  31. #include <cdpmain.h>
  32. #include <math.h>
  33. #include <mixxcon.h>
  34. #include <osbind.h>
  35. #include <standalone.h>
  36. #include <ctype.h>
  37. #include <sfsys.h>
  38. #include <string.h>
  39. #include <srates.h>
  40. #if defined unix || defined __GNUC__
  41. #define round(x) lround((x))
  42. #endif
  43. #ifndef HUGE
  44. #define HUGE 3.40282347e+38F
  45. #endif
  46. char errstr[2400];
  47. int anal_infiles = 1;
  48. int sloom = 0;
  49. int sloombatch = 0;
  50. const char* cdp_version = "7.1.0";
  51. //CDP LIB REPLACEMENTS
  52. static int setup_frame_arrays(dataptr dz);
  53. static int setup_frame_application(dataptr dz);
  54. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  55. static int parse_infile_and_check_type(char **cmdline,dataptr dz);
  56. static int setup_frame_param_ranges_and_defaults(dataptr dz);
  57. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz);
  58. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  59. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  60. static int establish_application(dataptr dz);
  61. static int initialise_vflags(dataptr dz);
  62. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  63. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  64. static int mark_parameter_types(dataptr dz,aplptr ap);
  65. static int assign_file_data_storage(int infilecnt,dataptr dz);
  66. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  67. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  68. static int get_the_mode_from_cmdline(char *str,dataptr dz);
  69. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  70. static int check_the_param_validity_and_consistency(dataptr dz);
  71. static int rotate(dataptr dz);
  72. static int read_the_special_data(char *filename,dataptr dz);
  73. static int snake_test(int n,double lasttime,int linecnt,char *filename,dataptr dz);
  74. static void get_next_snake(dataptr dz);
  75. static int get_first_rotation_orientation(int n,dataptr dz);
  76. static void set_stereo_levels(double pos, double *llevel, double *rlevel);
  77. static void do_smear(int loutchan,int routchan,double lsig,double rsig,int bufpos,int chans,float *obuf,double smear);
  78. static int reorient_test(dataptr dz);
  79. static int editchans_test(dataptr dz) ;
  80. static int reorient(dataptr dz);
  81. static int mirror(dataptr dz);
  82. static int bilateral(dataptr dz);
  83. static int beast_bilateral(dataptr dz);
  84. static int swapchans(dataptr dz);
  85. static int envchans(dataptr dz);
  86. #define FRAME_OCHAN_LEFT 0 /* the output left channel for output of moving sig, for each input channel, assuming sound is rotating round ring */
  87. #define FRAME_OCHAN_RIGHT 1 /* the output right channel for output of moving sig, for each input channel, assuming sound is rotating round ring */
  88. #define FRAME_OL 2 /* the output left channel for output of moving sig, for each input channel, once snaking has been factored in */
  89. #define FRAME_OR 3 /* the output right channel for output of moving sig, for each input channel, once snaking has been factored in */
  90. #define FRAME_SNAKE 4 /* store of ALL snaking values, over all times */
  91. #define FRAME_SNAKEPERM 5 /* current snake values */
  92. #define FRAME_ORIENT 6 /* orientation of first non-zero rotation : with 2 rotations, can be two values */
  93. #define FRAME_POS 0 /* inter-lspkr position at current time */
  94. #define FRAME_STEP 1 /* movement step between loudspeaker pair, same for every input channel : with 2 rotations, can be 2 step values */
  95. #define FRAME_LLEVEL 2 /* Relative level on left lspkr of a pair */
  96. #define FRAME_RLEVEL 3 /* Relative level on rigth lspkr of a pair */
  97. #define MAX_ROT 500 /* Max rate of frame-rotation: slow enough to ensure that spatial step between samples is NOT >= 1 */
  98. /* as alogirithm depends on intrer-speaker position (range 0-1) being reset within the 0-1 range simply by adding or subtracting 1 */
  99. /* whenever it oversteps those bounds, so can't step from any position WITHIN range, by >= 1 */
  100. #define ROTATION0 0
  101. #define ROTATION1 1
  102. #define EVEN(x) (!ODD(x))
  103. #define ROOT2 (1.4142136)
  104. #define next_snake_loc ringsize
  105. #define next_snake_time total_windows
  106. int SMEAR;
  107. /**************************************** MAIN *********************************************/
  108. int main(int argc,char *argv[])
  109. {
  110. int exit_status;
  111. dataptr dz = NULL;
  112. char **cmdline;
  113. int cmdlinecnt;
  114. int n;
  115. //aplptr ap;
  116. int is_launched = FALSE;
  117. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  118. fprintf(stdout,"%s\n",cdp_version);
  119. fflush(stdout);
  120. return 0;
  121. }
  122. /* CHECK FOR SOUNDLOOM */
  123. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  124. sloom = 0;
  125. sloombatch = 1;
  126. }
  127. if(sflinit("cdp")){
  128. sfperror("cdp: initialisation\n");
  129. return(FAILED);
  130. }
  131. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  132. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  133. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  134. return(FAILED);
  135. }
  136. if(!sloom) {
  137. if(argc == 1) {
  138. usage1();
  139. return(FAILED);
  140. } else if(argc == 2) {
  141. usage2(argv[1]);
  142. return(FAILED);
  143. }
  144. }
  145. dz->maxmode = 8;
  146. if(!sloom) {
  147. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  148. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  149. return(FAILED);
  150. }
  151. cmdline = argv;
  152. cmdlinecnt = argc;
  153. if((get_the_process_no(argv[0],dz))<0)
  154. return(FAILED);
  155. cmdline++;
  156. cmdlinecnt--;
  157. if((exit_status = get_the_mode_from_cmdline(cmdline[0],dz))<0) {
  158. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  159. return(exit_status);
  160. }
  161. cmdline++;
  162. cmdlinecnt--;
  163. // setup_particular_application =
  164. if((exit_status = setup_frame_application(dz))<0) {
  165. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  166. return(FAILED);
  167. }
  168. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  169. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  170. return(FAILED);
  171. }
  172. } else {
  173. //parse_TK_data() =
  174. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  175. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  176. return(exit_status);
  177. }
  178. }
  179. //ap = dz->application;
  180. switch(dz->mode) {
  181. case(0): SMEAR = 1; break;
  182. case(1): SMEAR = 2; break;
  183. }
  184. // parse_infile_and_hone_type() =
  185. if((exit_status = parse_infile_and_check_type(cmdline,dz))<0) {
  186. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  187. return(FAILED);
  188. }
  189. // setup_param_ranges_and_defaults() =
  190. if((exit_status = setup_frame_param_ranges_and_defaults(dz))<0) {
  191. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  192. return(FAILED);
  193. }
  194. // open_first_infile CDP LIB
  195. if((exit_status = open_first_infile(cmdline[0],dz))<0) {
  196. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  197. return(FAILED);
  198. }
  199. cmdlinecnt--;
  200. cmdline++;
  201. // handle_extra_infiles() : redundant
  202. // handle_outfile() =
  203. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,dz))<0) {
  204. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  205. return(FAILED);
  206. }
  207. // handle_formants() redundant
  208. // handle_formant_quiksearch() redundant
  209. if((dz->mode < 3) || (dz->mode == 6)) {
  210. if((exit_status = read_the_special_data(cmdline[0],dz))<0) {
  211. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  212. return(FAILED);
  213. }
  214. cmdlinecnt--;
  215. cmdline++;
  216. }
  217. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  218. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  219. return(FAILED);
  220. }
  221. // check_param_validity_and_consistency....
  222. if((exit_status = check_the_param_validity_and_consistency(dz))<0) {
  223. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  224. return(FAILED);
  225. }
  226. if(dz->mode != 6) {
  227. if((exit_status = setup_frame_arrays(dz))<0) {
  228. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  229. return(FAILED);
  230. }
  231. }
  232. is_launched = TRUE;
  233. dz->bufcnt = 2;
  234. if((dz->sampbuf = (float **)malloc(sizeof(float *) * (dz->bufcnt+1)))==NULL) {
  235. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffers.\n");
  236. return(MEMORY_ERROR);
  237. }
  238. if((dz->sbufptr = (float **)malloc(sizeof(float *) * dz->bufcnt))==NULL) {
  239. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffer pointers.\n");
  240. return(MEMORY_ERROR);
  241. }
  242. for(n = 0;n <dz->bufcnt; n++)
  243. dz->sampbuf[n] = dz->sbufptr[n] = (float *)0;
  244. dz->sampbuf[n] = (float *)0;
  245. if((exit_status = create_sndbufs(dz))<0) { // CDP LIB
  246. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  247. return(FAILED);
  248. }
  249. //param_preprocess() redundant
  250. //spec_process_file =
  251. switch(dz->mode) {
  252. case(2):
  253. case(3):
  254. case(4):
  255. case(7):
  256. if((exit_status = reorient(dz))<0) {
  257. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  258. return(FAILED);
  259. }
  260. break;
  261. case(5):
  262. if((exit_status = swapchans(dz))<0) {
  263. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  264. return(FAILED);
  265. }
  266. break;
  267. case(6):
  268. if((exit_status = envchans(dz))<0) {
  269. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  270. return(FAILED);
  271. }
  272. break;
  273. default:
  274. if((exit_status = rotate(dz))<0) {
  275. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  276. return(FAILED);
  277. }
  278. break;
  279. }
  280. if((exit_status = complete_output(dz))<0) { // CDP LIB
  281. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  282. return(FAILED);
  283. }
  284. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  285. free(dz);
  286. return(SUCCEEDED);
  287. }
  288. /**********************************************
  289. REPLACED CDP LIB FUNCTIONS
  290. **********************************************/
  291. /****************************** SET_PARAM_DATA *********************************/
  292. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  293. {
  294. ap->special_data = (char)special_data;
  295. ap->param_cnt = (char)paramcnt;
  296. ap->max_param_cnt = (char)maxparamcnt;
  297. if(ap->max_param_cnt>0) {
  298. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  299. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  300. return(MEMORY_ERROR);
  301. }
  302. strcpy(ap->param_list,paramlist);
  303. }
  304. return(FINISHED);
  305. }
  306. /****************************** SET_VFLGS *********************************/
  307. int set_vflgs
  308. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  309. {
  310. ap->option_cnt = (char) optcnt; /*RWD added cast */
  311. if(optcnt) {
  312. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  313. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  314. return(MEMORY_ERROR);
  315. }
  316. strcpy(ap->option_list,optlist);
  317. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  318. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  319. return(MEMORY_ERROR);
  320. }
  321. strcpy(ap->option_flags,optflags);
  322. }
  323. ap->vflag_cnt = (char) vflagcnt;
  324. ap->variant_param_cnt = (char) vparamcnt;
  325. if(vflagcnt) {
  326. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  327. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  328. return(MEMORY_ERROR);
  329. }
  330. strcpy(ap->variant_list,varlist);
  331. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  332. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  333. return(MEMORY_ERROR);
  334. }
  335. strcpy(ap->variant_flags,varflags);
  336. }
  337. return(FINISHED);
  338. }
  339. /***************************** APPLICATION_INIT **************************/
  340. int application_init(dataptr dz)
  341. {
  342. int exit_status;
  343. int storage_cnt;
  344. int tipc, brkcnt;
  345. aplptr ap = dz->application;
  346. if(ap->vflag_cnt>0)
  347. initialise_vflags(dz);
  348. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  349. ap->total_input_param_cnt = (char)tipc;
  350. if(tipc>0) {
  351. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  352. return(exit_status);
  353. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  354. return(exit_status);
  355. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  356. return(exit_status);
  357. }
  358. brkcnt = tipc;
  359. //THERE ARE NO INPUTFILE brktables USED IN THIS PROCESS
  360. if(brkcnt>0) {
  361. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  362. return(exit_status);
  363. }
  364. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  365. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  366. return(exit_status);
  367. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  368. return(exit_status);
  369. }
  370. if((exit_status = mark_parameter_types(dz,ap))<0)
  371. return(exit_status);
  372. // establish_infile_constants() replaced by
  373. dz->infilecnt = 1;
  374. //establish_bufptrs_and_extra_buffers():
  375. if((exit_status = setup_internal_arrays_and_array_pointers(dz))<0)
  376. return(exit_status);
  377. return(FINISHED);
  378. }
  379. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  380. /* RWD mallo changed to calloc; helps debug verison run as release! */
  381. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  382. {
  383. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  384. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  385. return(MEMORY_ERROR);
  386. }
  387. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  388. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  389. return(MEMORY_ERROR);
  390. }
  391. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  392. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  393. return(MEMORY_ERROR);
  394. }
  395. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  396. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  397. return(MEMORY_ERROR);
  398. }
  399. return(FINISHED);
  400. }
  401. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  402. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  403. {
  404. int n;
  405. for(n=0;n<storage_cnt;n++) {
  406. dz->is_int[n] = (char)0;
  407. dz->no_brk[n] = (char)0;
  408. }
  409. return(FINISHED);
  410. }
  411. /***************************** MARK_PARAMETER_TYPES **************************/
  412. int mark_parameter_types(dataptr dz,aplptr ap)
  413. {
  414. int n, m; /* PARAMS */
  415. for(n=0;n<ap->max_param_cnt;n++) {
  416. switch(ap->param_list[n]) {
  417. case('0'): break; /* dz->is_active[n] = 0 is default */
  418. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  419. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  420. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  421. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  422. default:
  423. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  424. return(PROGRAM_ERROR);
  425. }
  426. } /* OPTIONS */
  427. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  428. switch(ap->option_list[n]) {
  429. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  430. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  431. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  432. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  433. default:
  434. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  435. return(PROGRAM_ERROR);
  436. }
  437. } /* VARIANTS */
  438. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  439. switch(ap->variant_list[n]) {
  440. case('0'): break;
  441. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  442. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  443. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  444. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  445. default:
  446. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  447. return(PROGRAM_ERROR);
  448. }
  449. } /* INTERNAL */
  450. for(n=0,
  451. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  452. switch(ap->internal_param_list[n]) {
  453. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  454. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  455. case('d'): dz->no_brk[m] = (char)1; break;
  456. default:
  457. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  458. return(PROGRAM_ERROR);
  459. }
  460. }
  461. return(FINISHED);
  462. }
  463. /************************ HANDLE_THE_OUTFILE *********************/
  464. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz)
  465. {
  466. int exit_status;
  467. char *filename = (*cmdline)[0];
  468. if(filename[0]=='-' && filename[1]=='f') {
  469. dz->floatsam_output = 1;
  470. dz->true_outfile_stype = SAMP_FLOAT;
  471. filename+= 2;
  472. }
  473. if(!sloom) {
  474. if(file_has_invalid_startchar(filename) || value_is_numeric(filename)) {
  475. sprintf(errstr,"Outfile name %s has invalid start character(s) or looks too much like a number.\n",filename);
  476. return(DATA_ERROR);
  477. }
  478. }
  479. strcpy(dz->outfilename,filename);
  480. if((exit_status = create_sized_outfile(filename,dz))<0)
  481. return(exit_status);
  482. (*cmdline)++;
  483. (*cmdlinecnt)--;
  484. return(FINISHED);
  485. }
  486. /***************************** ESTABLISH_APPLICATION **************************/
  487. int establish_application(dataptr dz)
  488. {
  489. aplptr ap;
  490. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  491. sprintf(errstr,"establish_application()\n");
  492. return(MEMORY_ERROR);
  493. }
  494. ap = dz->application;
  495. memset((char *)ap,0,sizeof(struct applic));
  496. return(FINISHED);
  497. }
  498. /************************* INITIALISE_VFLAGS *************************/
  499. int initialise_vflags(dataptr dz)
  500. {
  501. int n;
  502. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  503. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  504. return(MEMORY_ERROR);
  505. }
  506. for(n=0;n<dz->application->vflag_cnt;n++)
  507. dz->vflag[n] = FALSE;
  508. return FINISHED;
  509. }
  510. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  511. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  512. {
  513. int n;
  514. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  515. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  516. return(MEMORY_ERROR);
  517. }
  518. for(n=0;n<tipc;n++)
  519. ap->default_val[n] = 0.0;
  520. return(FINISHED);
  521. }
  522. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  523. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  524. {
  525. int n;
  526. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  527. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  528. return(MEMORY_ERROR);
  529. }
  530. for(n=0;n<tipc;n++)
  531. dz->is_active[n] = (char)0;
  532. return(FINISHED);
  533. }
  534. /************************* SETUP_FRAME_APPLICATION *******************/
  535. int setup_frame_application(dataptr dz)
  536. {
  537. int exit_status;
  538. aplptr ap;
  539. if((exit_status = establish_application(dz))<0) // GLOBAL
  540. return(FAILED);
  541. ap = dz->application;
  542. // SEE parstruct FOR EXPLANATION of next 2 functions
  543. switch(dz->mode) {
  544. case(0):
  545. if((exit_status = set_param_data(ap,FRAMEDATA ,1,1,"D"))<0)
  546. return(FAILED);
  547. if((exit_status = set_vflgs(ap,"s",1,"d","",0,0,""))<0)
  548. return(FAILED);
  549. break;
  550. case(1):
  551. if((exit_status = set_param_data(ap,FRAMEDATA ,2,2,"DD"))<0)
  552. return(FAILED);
  553. if((exit_status = set_vflgs(ap,"s",1,"d","",0,0,""))<0)
  554. return(FAILED);
  555. break;
  556. case(2):
  557. if((exit_status = set_param_data(ap,FRAMEDATA ,0,0,""))<0)
  558. return(FAILED);
  559. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  560. return(FAILED);
  561. break;
  562. case(3):
  563. if((exit_status = set_param_data(ap,0,1,1,"d"))<0)
  564. return(FAILED);
  565. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  566. return(FAILED);
  567. break;
  568. case(4):
  569. if((exit_status = set_param_data(ap,0,0,0,""))<0)
  570. return(FAILED);
  571. if((exit_status = set_vflgs(ap,"",0,"","b",1,0,"0"))<0)
  572. return(FAILED);
  573. break;
  574. case(5):
  575. if((exit_status = set_param_data(ap,0,2,2,"ii"))<0)
  576. return(FAILED);
  577. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  578. return(FAILED);
  579. break;
  580. case(6):
  581. if((exit_status = set_param_data(ap,FRAMEDATA,1,1,"D"))<0)
  582. return(FAILED);
  583. if((exit_status = set_vflgs(ap,"",0,"","",0,0,"0"))<0)
  584. return(FAILED);
  585. break;
  586. case(7):
  587. if((exit_status = set_param_data(ap,0,0,0,""))<0)
  588. return(FAILED);
  589. if((exit_status = set_vflgs(ap,"",0,"","b",1,0,"0"))<0)
  590. return(FAILED);
  591. break;
  592. }
  593. // set_legal_infile_structure -->
  594. dz->has_otherfile = FALSE;
  595. // assign_process_logic -->
  596. dz->input_data_type = SNDFILES_ONLY;
  597. dz->process_type = EQUAL_SNDFILE;
  598. dz->outfiletype = SNDFILE_OUT;
  599. return application_init(dz); //GLOBAL
  600. }
  601. /************************* PARSE_INFILE_AND_CHECK_TYPE *******************/
  602. int parse_infile_and_check_type(char **cmdline,dataptr dz)
  603. {
  604. int exit_status;
  605. infileptr infile_info;
  606. if(!sloom) {
  607. if((infile_info = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  608. sprintf(errstr,"INSUFFICIENT MEMORY for infile structure to test file data.");
  609. return(MEMORY_ERROR);
  610. } else if((exit_status = cdparse(cmdline[0],infile_info))<0) {
  611. sprintf(errstr,"Failed to parse input file %s\n",cmdline[0]);
  612. return(PROGRAM_ERROR);
  613. } else if(infile_info->filetype != SNDFILE) {
  614. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  615. return(DATA_ERROR);
  616. } else if(infile_info->channels < 2) {
  617. sprintf(errstr,"File %s is not of correct type (must be multichannel)\n",cmdline[0]);
  618. return(DATA_ERROR);
  619. }
  620. if((dz->mode == 1) && ODD(infile_info->channels)) {
  621. sprintf(errstr,"File %s is not of correct type (must have even number of channels)\n",cmdline[0]);
  622. return(DATA_ERROR);
  623. }
  624. if((exit_status = copy_parse_info_to_main_structure(infile_info,dz))<0) {
  625. sprintf(errstr,"Failed to copy file parsing information\n");
  626. return(PROGRAM_ERROR);
  627. }
  628. free(infile_info);
  629. }
  630. return(FINISHED);
  631. }
  632. /************************* SETUP_FRAME_PARAM_RANGES_AND_DEFAULTS *******************/
  633. int setup_frame_param_ranges_and_defaults(dataptr dz)
  634. {
  635. int exit_status;
  636. aplptr ap = dz->application;
  637. // set_param_ranges()
  638. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  639. // NB total_input_param_cnt is > 0 !!!
  640. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  641. return(FAILED);
  642. // get_param_ranges()
  643. switch(dz->mode) {
  644. case(1):
  645. ap->lo[1] = -500.0;
  646. ap->hi[1] = 500.0;
  647. ap->default_val[1] = -1.0;
  648. /* fall thro */
  649. case(0):
  650. ap->lo[0] = -MAX_ROT;
  651. ap->hi[0] = MAX_ROT;
  652. ap->default_val[0] = 1.0;
  653. ap->lo[SMEAR] = 0.0;
  654. ap->hi[SMEAR] = 0.5;
  655. ap->default_val[SMEAR] = 0.0;
  656. break;
  657. case(2):
  658. case(4):
  659. break;
  660. case(3):
  661. ap->lo[0] = 0.0;
  662. ap->hi[0] = 16.5;
  663. ap->default_val[0] = 1.0;
  664. break;
  665. case(5):
  666. ap->lo[0] = 1.0;
  667. ap->hi[0] = 16.0;
  668. ap->default_val[0] = 1.0;
  669. ap->lo[1] = 1.0;
  670. ap->hi[1] = 16.0;
  671. ap->default_val[1] = 2.0;
  672. break;
  673. case(6):
  674. ap->lo[0] = 0.0;
  675. ap->hi[0] = 1.0;
  676. ap->default_val[0] = 0.0;
  677. break;
  678. }
  679. if(!sloom)
  680. put_default_vals_in_all_params(dz);
  681. return(FINISHED);
  682. }
  683. /********************************* PARSE_SLOOM_DATA *********************************/
  684. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  685. {
  686. int exit_status;
  687. int cnt = 1, infilecnt;
  688. int filesize, insams, inbrksize;
  689. double dummy;
  690. int true_cnt = 0;
  691. // aplptr ap;
  692. while(cnt<=PRE_CMDLINE_DATACNT) {
  693. if(cnt > argc) {
  694. sprintf(errstr,"Insufficient data sent from TK\n");
  695. return(DATA_ERROR);
  696. }
  697. switch(cnt) {
  698. case(1):
  699. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  700. sprintf(errstr,"Cannot read process no. sent from TK\n");
  701. return(DATA_ERROR);
  702. }
  703. break;
  704. case(2):
  705. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  706. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  707. return(DATA_ERROR);
  708. }
  709. if(dz->mode > 0)
  710. dz->mode--;
  711. //setup_particular_application() =
  712. if((exit_status = setup_frame_application(dz))<0)
  713. return(exit_status);
  714. //ap = dz->application;
  715. break;
  716. case(3):
  717. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  718. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  719. return(DATA_ERROR);
  720. }
  721. if(infilecnt < 1) {
  722. true_cnt = cnt + 1;
  723. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  724. }
  725. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  726. return(exit_status);
  727. break;
  728. case(INPUT_FILETYPE+4):
  729. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  730. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  731. return(DATA_ERROR);
  732. }
  733. break;
  734. case(INPUT_FILESIZE+4):
  735. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  736. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  737. return(DATA_ERROR);
  738. }
  739. dz->insams[0] = filesize;
  740. break;
  741. case(INPUT_INSAMS+4):
  742. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  743. sprintf(errstr,"Cannot read insams sent from TK\n");
  744. return(DATA_ERROR);
  745. }
  746. dz->insams[0] = insams;
  747. break;
  748. case(INPUT_SRATE+4):
  749. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  750. sprintf(errstr,"Cannot read srate sent from TK\n");
  751. return(DATA_ERROR);
  752. }
  753. break;
  754. case(INPUT_CHANNELS+4):
  755. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  756. sprintf(errstr,"Cannot read channels sent from TK\n");
  757. return(DATA_ERROR);
  758. }
  759. break;
  760. case(INPUT_STYPE+4):
  761. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  762. sprintf(errstr,"Cannot read stype sent from TK\n");
  763. return(DATA_ERROR);
  764. }
  765. break;
  766. case(INPUT_ORIGSTYPE+4):
  767. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  768. sprintf(errstr,"Cannot read origstype sent from TK\n");
  769. return(DATA_ERROR);
  770. }
  771. break;
  772. case(INPUT_ORIGRATE+4):
  773. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  774. sprintf(errstr,"Cannot read origrate sent from TK\n");
  775. return(DATA_ERROR);
  776. }
  777. break;
  778. case(INPUT_MLEN+4):
  779. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  780. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  781. return(DATA_ERROR);
  782. }
  783. break;
  784. case(INPUT_DFAC+4):
  785. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  786. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  787. return(DATA_ERROR);
  788. }
  789. break;
  790. case(INPUT_ORIGCHANS+4):
  791. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  792. sprintf(errstr,"Cannot read origchans sent from TK\n");
  793. return(DATA_ERROR);
  794. }
  795. break;
  796. case(INPUT_SPECENVCNT+4):
  797. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  798. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  799. return(DATA_ERROR);
  800. }
  801. dz->specenvcnt = dz->infile->specenvcnt;
  802. break;
  803. case(INPUT_WANTED+4):
  804. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  805. sprintf(errstr,"Cannot read wanted sent from TK\n");
  806. return(DATA_ERROR);
  807. }
  808. break;
  809. case(INPUT_WLENGTH+4):
  810. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  811. sprintf(errstr,"Cannot read wlength sent from TK\n");
  812. return(DATA_ERROR);
  813. }
  814. break;
  815. case(INPUT_OUT_CHANS+4):
  816. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  817. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  818. return(DATA_ERROR);
  819. }
  820. break;
  821. /* RWD these chanegs to samps - tk will have to deal with that! */
  822. case(INPUT_DESCRIPTOR_BYTES+4):
  823. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  824. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  825. return(DATA_ERROR);
  826. }
  827. break;
  828. case(INPUT_IS_TRANSPOS+4):
  829. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  830. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  831. return(DATA_ERROR);
  832. }
  833. break;
  834. case(INPUT_COULD_BE_TRANSPOS+4):
  835. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  836. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  837. return(DATA_ERROR);
  838. }
  839. break;
  840. case(INPUT_COULD_BE_PITCH+4):
  841. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  842. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  843. return(DATA_ERROR);
  844. }
  845. break;
  846. case(INPUT_DIFFERENT_SRATES+4):
  847. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  848. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  849. return(DATA_ERROR);
  850. }
  851. break;
  852. case(INPUT_DUPLICATE_SNDS+4):
  853. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  854. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  855. return(DATA_ERROR);
  856. }
  857. break;
  858. case(INPUT_BRKSIZE+4):
  859. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  860. sprintf(errstr,"Cannot read brksize sent from TK\n");
  861. return(DATA_ERROR);
  862. }
  863. if(inbrksize > 0) {
  864. switch(dz->input_data_type) {
  865. case(WORDLIST_ONLY):
  866. break;
  867. case(PITCH_AND_PITCH):
  868. case(PITCH_AND_TRANSPOS):
  869. case(TRANSPOS_AND_TRANSPOS):
  870. dz->tempsize = inbrksize;
  871. break;
  872. case(BRKFILES_ONLY):
  873. case(UNRANGED_BRKFILE_ONLY):
  874. case(DB_BRKFILES_ONLY):
  875. case(ALL_FILES):
  876. case(ANY_NUMBER_OF_ANY_FILES):
  877. if(dz->extrabrkno < 0) {
  878. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  879. return(DATA_ERROR);
  880. }
  881. if(dz->brksize == NULL) {
  882. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  883. return(PROGRAM_ERROR);
  884. }
  885. dz->brksize[dz->extrabrkno] = inbrksize;
  886. break;
  887. default:
  888. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  889. dz->input_data_type);
  890. return(PROGRAM_ERROR);
  891. }
  892. break;
  893. }
  894. break;
  895. case(INPUT_NUMSIZE+4):
  896. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  897. sprintf(errstr,"Cannot read numsize sent from TK\n");
  898. return(DATA_ERROR);
  899. }
  900. break;
  901. case(INPUT_LINECNT+4):
  902. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  903. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  904. return(DATA_ERROR);
  905. }
  906. break;
  907. case(INPUT_ALL_WORDS+4):
  908. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  909. sprintf(errstr,"Cannot read all_words sent from TK\n");
  910. return(DATA_ERROR);
  911. }
  912. break;
  913. case(INPUT_ARATE+4):
  914. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  915. sprintf(errstr,"Cannot read arate sent from TK\n");
  916. return(DATA_ERROR);
  917. }
  918. break;
  919. case(INPUT_FRAMETIME+4):
  920. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  921. sprintf(errstr,"Cannot read frametime sent from TK\n");
  922. return(DATA_ERROR);
  923. }
  924. dz->frametime = (float)dummy;
  925. break;
  926. case(INPUT_WINDOW_SIZE+4):
  927. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  928. sprintf(errstr,"Cannot read window_size sent from TK\n");
  929. return(DATA_ERROR);
  930. }
  931. break;
  932. case(INPUT_NYQUIST+4):
  933. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  934. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  935. return(DATA_ERROR);
  936. }
  937. break;
  938. case(INPUT_DURATION+4):
  939. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  940. sprintf(errstr,"Cannot read duration sent from TK\n");
  941. return(DATA_ERROR);
  942. }
  943. break;
  944. case(INPUT_MINBRK+4):
  945. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  946. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  947. return(DATA_ERROR);
  948. }
  949. break;
  950. case(INPUT_MAXBRK+4):
  951. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  952. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  953. return(DATA_ERROR);
  954. }
  955. break;
  956. case(INPUT_MINNUM+4):
  957. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  958. sprintf(errstr,"Cannot read minnum sent from TK\n");
  959. return(DATA_ERROR);
  960. }
  961. break;
  962. case(INPUT_MAXNUM+4):
  963. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  964. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  965. return(DATA_ERROR);
  966. }
  967. break;
  968. default:
  969. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  970. return(PROGRAM_ERROR);
  971. }
  972. cnt++;
  973. }
  974. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  975. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  976. return(DATA_ERROR);
  977. }
  978. if(true_cnt)
  979. cnt = true_cnt;
  980. *cmdlinecnt = 0;
  981. while(cnt < argc) {
  982. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  983. return(exit_status);
  984. cnt++;
  985. }
  986. return(FINISHED);
  987. }
  988. /********************************* GET_TK_CMDLINE_WORD *********************************/
  989. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  990. {
  991. if(*cmdlinecnt==0) {
  992. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  993. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  994. return(MEMORY_ERROR);
  995. }
  996. } else {
  997. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  998. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  999. return(MEMORY_ERROR);
  1000. }
  1001. }
  1002. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  1003. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  1004. return(MEMORY_ERROR);
  1005. }
  1006. strcpy((*cmdline)[*cmdlinecnt],q);
  1007. (*cmdlinecnt)++;
  1008. return(FINISHED);
  1009. }
  1010. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  1011. int assign_file_data_storage(int infilecnt,dataptr dz)
  1012. {
  1013. int exit_status;
  1014. int no_sndfile_system_files = FALSE;
  1015. dz->infilecnt = infilecnt;
  1016. if((exit_status = allocate_filespace(dz))<0)
  1017. return(exit_status);
  1018. if(no_sndfile_system_files)
  1019. dz->infilecnt = 0;
  1020. return(FINISHED);
  1021. }
  1022. /************************* SETUP_INTERNAL_ARRAYS_AND_ARRAY_POINTERS *******************/
  1023. int setup_internal_arrays_and_array_pointers(dataptr dz)
  1024. {
  1025. int n;
  1026. dz->larray_cnt = 7;
  1027. dz->array_cnt = 4;
  1028. if((dz->parray = (double **)malloc(dz->array_cnt * sizeof(double *)))==NULL) {
  1029. sprintf(errstr,"INSUFFICIENT MEMORY for internal double array.\n");
  1030. return(MEMORY_ERROR);
  1031. }
  1032. if((dz->lparray = (int **)malloc(dz->larray_cnt * sizeof(int *)))==NULL) {
  1033. sprintf(errstr,"INSUFFICIENT MEMORY for internal long arrays.\n");
  1034. return(MEMORY_ERROR);
  1035. }
  1036. for(n=0;n<dz->larray_cnt;n++)
  1037. dz->lparray[n] = NULL;
  1038. return(FINISHED);
  1039. }
  1040. /************************* redundant functions: to ensure libs compile OK *******************/
  1041. int assign_process_logic(dataptr dz)
  1042. {
  1043. return(FINISHED);
  1044. }
  1045. void set_legal_infile_structure(dataptr dz)
  1046. {}
  1047. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  1048. {
  1049. return(FINISHED);
  1050. }
  1051. int establish_bufptrs_and_extra_buffers(dataptr dz)
  1052. {
  1053. return(FINISHED);
  1054. }
  1055. int read_special_data(char *str,dataptr dz)
  1056. {
  1057. return(FINISHED);
  1058. }
  1059. int inner_loop
  1060. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  1061. {
  1062. return(FINISHED);
  1063. }
  1064. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1065. {
  1066. return(FINISHED);
  1067. }
  1068. /******************************** USAGE1 ********************************/
  1069. int usage1(void)
  1070. {
  1071. usage2("shift");
  1072. return(USAGE_ONLY);
  1073. }
  1074. /**************************** SETUP_FRAME_ARRAYS *****************************/
  1075. int setup_frame_arrays(dataptr dz)
  1076. {
  1077. int chans = dz->infile->channels;
  1078. if((dz->lparray[FRAME_OCHAN_LEFT] = malloc(chans * sizeof(int)))==NULL) {
  1079. sprintf(errstr,"Insufficient memory to store left-rotation data.\n");
  1080. return(MEMORY_ERROR);
  1081. }
  1082. if((dz->lparray[FRAME_OCHAN_RIGHT] = malloc(chans * sizeof(int)))==NULL) {
  1083. sprintf(errstr,"Insufficient memory to store right-rotation data.\n");
  1084. return(MEMORY_ERROR);
  1085. }
  1086. if((dz->lparray[FRAME_OL] = malloc(chans * sizeof(int)))==NULL) {
  1087. sprintf(errstr,"Insufficient memory to store snaked-left-rotation data.\n");
  1088. return(MEMORY_ERROR);
  1089. }
  1090. if((dz->lparray[FRAME_OR] = malloc(chans * sizeof(int)))==NULL) {
  1091. sprintf(errstr,"Insufficient memory to store snaked-right-rotation data.\n");
  1092. return(MEMORY_ERROR);
  1093. }
  1094. if((dz->lparray[FRAME_SNAKEPERM] = malloc(chans * sizeof(int)))==NULL) {
  1095. sprintf(errstr,"Insufficient memory to store current snake permutation data.\n");
  1096. return(MEMORY_ERROR);
  1097. }
  1098. if((dz->lparray[FRAME_ORIENT] = malloc(2 * sizeof(int)))==NULL) {
  1099. sprintf(errstr,"Insufficient memory to store first_orientation vals.\n");
  1100. return(MEMORY_ERROR);
  1101. }
  1102. if((dz->parray[FRAME_POS] = malloc(2 * sizeof(double)))==NULL) {
  1103. sprintf(errstr,"Insufficient memory to store rotation data.\n");
  1104. return(MEMORY_ERROR);
  1105. }
  1106. if((dz->parray[FRAME_STEP] = malloc(2 * sizeof(double)))==NULL) {
  1107. sprintf(errstr,"Insufficient memory to store spatial step data.\n");
  1108. return(MEMORY_ERROR);
  1109. }
  1110. if((dz->parray[FRAME_LLEVEL] = malloc(2 * sizeof(double)))==NULL) {
  1111. sprintf(errstr,"Insufficient memory to store left level vals.\n");
  1112. return(MEMORY_ERROR);
  1113. }
  1114. if((dz->parray[FRAME_RLEVEL] = malloc(2 * sizeof(double)))==NULL) {
  1115. sprintf(errstr,"Insufficient memory to store right level vals.\n");
  1116. return(MEMORY_ERROR);
  1117. }
  1118. return FINISHED;
  1119. }
  1120. /********************************************************************************************/
  1121. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1122. {
  1123. if(!strcmp(prog_identifier_from_cmdline,"shift")) dz->process = FRAME;
  1124. else {
  1125. sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  1126. return(USAGE_ONLY);
  1127. }
  1128. return(FINISHED);
  1129. }
  1130. /****************************** GET_MODE *********************************/
  1131. int get_the_mode_from_cmdline(char *str,dataptr dz)
  1132. {
  1133. if(sscanf(str,"%d",&dz->mode)!=1) {
  1134. sprintf(errstr,"Cannot read mode of program.\n");
  1135. return(USAGE_ONLY);
  1136. }
  1137. if(dz->mode <= 0 || dz->mode > dz->maxmode) {
  1138. sprintf(errstr,"Program mode value [%d] is out of range [1 - %d].\n",dz->mode,dz->maxmode);
  1139. return(USAGE_ONLY);
  1140. }
  1141. dz->mode--; /* CHANGE TO INTERNAL REPRESENTATION OF MODE NO */
  1142. return(FINISHED);
  1143. }
  1144. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  1145. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  1146. {
  1147. int n;
  1148. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1149. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  1150. return(MEMORY_ERROR);
  1151. }
  1152. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1153. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  1154. return(MEMORY_ERROR);
  1155. }
  1156. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1157. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  1158. return(MEMORY_ERROR);
  1159. }
  1160. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1161. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  1162. return(MEMORY_ERROR);
  1163. }
  1164. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1165. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  1166. return(MEMORY_ERROR);
  1167. }
  1168. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1169. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  1170. return(MEMORY_ERROR);
  1171. }
  1172. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1173. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  1174. return(MEMORY_ERROR);
  1175. }
  1176. for(n=0;n<brkcnt;n++) {
  1177. dz->brk[n] = NULL;
  1178. dz->brkptr[n] = NULL;
  1179. dz->brkinit[n] = 0;
  1180. dz->brksize[n] = 0;
  1181. }
  1182. return(FINISHED);
  1183. }
  1184. /******************************** USAGE2 ********************************/
  1185. int usage2(char *str)
  1186. {
  1187. if(!strcmp(str,"shift")) {
  1188. fprintf(stderr,
  1189. "USAGE:\n"
  1190. "frame shift 1 infile outfile snake rotation [-ssmear]\n"
  1191. "frame shift 2 infile outfile snake rotation1 rotation2 [-ssmear]\n"
  1192. "frame shift 3 infile outfile reorient\n"
  1193. "frame shift 4 infile outfile mirrorplane\n"
  1194. "frame shift 5 infile outfile [-b]\n"
  1195. "frame shift 6 infile outfile swapA swapB\n"
  1196. "frame shift 7 infile outfile chaninfo gain\n"
  1197. "frame shift 8 infile outfile [-b]\n"
  1198. "\n"
  1199. "Modes 1 & 2 Rotate the entire frame of a multichannel file.\n"
  1200. "Mode 3 Changes the channel assignment of a multichannel file.\n"
  1201. "Mode 4 Mirrors the channel output around specified mirrorplane.\n"
  1202. "Mode 5 Converts between ring-numbered & bilaterally numbered outchans.\n"
  1203. "Mode 6 Swaps any pair of channels (swapA and swapB).\n"
  1204. "Mode 7 Allows any channel, or set of channels, to be enveloped,\n"
  1205. " independently of the other channels.\n"
  1206. "Mode 8 Converts between ring-numbered & BEAST bilateral numbering.\n"
  1207. "\n"
  1208. "ROTATION rotation-rate in cycles (complete frame-rotations) per sec.\n"
  1209. " Mode 2 (only with files with even number of input channels)\n"
  1210. " rotates odd & even chans independently; has 2 rotation vals.\n"
  1211. " Negative values produce anticlockwise rotation.\n"
  1212. " Rotation rate can vary through time. Range -500 to +500.\n"
  1213. "SMEAR Extent to which channel-signals bleed onto adjacent chans.\n"
  1214. " (range 0 to 0.5 : default 0)\n"
  1215. "SNAKE In clockwise rotation,in (e.g.) 8 chans, input chan-1 follows\n"
  1216. " the route 1->2->3->4->5->6->7->8->1 etc. around lspkrs.\n"
  1217. " Other input chans form a \"snake\" following chan-1 round.\n"
  1218. " To produce rotation (default) set '\"snake\" to ZERO.\n"
  1219. " HOWEVER, channels might snake along a different route,\n"
  1220. " & route (which could vary over time) can be specified\n"
  1221. " in a data file of \"time : snake-list\" values\n"
  1222. " e.g. might specify route at time zero ,for 8-chan file\n"
  1223. " \"0.0 8 6 5 2 7 3 4 1\" & change route at a later time\n"
  1224. " e.g. \"1.378245 4 1 5 2 6 7 8 3\"\n"
  1225. " 1st time-val in data must be zero. Times must increase.\n"
  1226. " IN MODE 2, odd & even chans rotate independently.\n"
  1227. " 1->3->5->7->1 etc and 2->4->6->8->2 etc\n"
  1228. " Snake data directs motion round a different route.\n"
  1229. " e.g. the snake \"8 6 5 2 7 3 4 1\" above\n"
  1230. " produces one snake around the odd entries\n"
  1231. " i.e. 8 -> 5 -> 7 -> 4 -> 8 etc\n"
  1232. " and a 2nd snake around the even entries\n"
  1233. " i.e. 6 -> 2 -> 3 -> 1 -> 6 etc\n"
  1234. "REORIENT List of ALL input chans, in new positions they will have.\n"
  1235. " e.g. for 4-chans: Data 4 1 2 3\n"
  1236. " sends Ch1 to 4, Ch2 -> 1, Ch3 -> 2 and Ch4 -> 3\n"
  1237. "MIRRORPLANE Line around which frame is (symmetrically) mirrored.\n"
  1238. " Values can be any (integer) outchannel number OR\n"
  1239. " any half-way position between outchans e.g. 1.5, 2.5\n"
  1240. " With N chans, 'N.5' lies between Nth & 1st chan.\n"
  1241. "-b (Mode 5) Convert bilateral to ring (Default, ring to bilateral).\n"
  1242. " Numbering of outchans can be ring, or bilateral.\n"
  1243. " e.g. for 7 outchans ...\n"
  1244. " RING BILATERAL\n"
  1245. " 1 1\n"
  1246. " 7 2 2 3\n"
  1247. " 6 3 4 5\n"
  1248. " 5 4 6 7\n"
  1249. " All multichan pan programs assume RING numbering.\n"
  1250. " Use this mode to convert out of and into bilateral format.\n"
  1251. "-b (Mode 8) Convert BEAST bilateral to ring (Default, ring to BEAST).\n"
  1252. " BEAST bilateral numbering for 8 outchans ...\n"
  1253. " RING BEAST\n"
  1254. " 1 7\n"
  1255. " 8 2 1 2\n"
  1256. " 7 3 3 4\n"
  1257. " 6 4 5 6\n"
  1258. " 5 8\n"
  1259. "SWAPA,SWAPB The 2 channels that are to be swapped.\n"
  1260. "CHANINFO A single channel number, or a list of channels in a file.\n"
  1261. "GAIN Gain to apply to enveloped channels (can vary over time).\n");
  1262. } else
  1263. fprintf(stdout,"Unknown option '%s'\n",str);
  1264. return(USAGE_ONLY);
  1265. }
  1266. int usage3(char *str1,char *str2)
  1267. {
  1268. fprintf(stderr,"Insufficient parameters on command line.\n");
  1269. return(USAGE_ONLY);
  1270. }
  1271. /******************************** FRAME ********************************/
  1272. int rotate(dataptr dz)
  1273. {
  1274. int exit_status, n;
  1275. int chans = dz->infile->channels, out_lspkr_step; /* out_lspkr_step: For single rotation, step between adjacent lspkrs, out_lspkr_step is 1 */
  1276. double time, srate = (double)dz->infile->srate; /* For double rotation, step between even lspkrs (or between odd), out_lspkr_step is 2 */
  1277. int nextclick;
  1278. int click = (int)round(srate/(double)MAX_ROT) * chans; /* Timestep between each reading of rotation-speed brktables */
  1279. double *inter_lspkr_position = dz->parray[FRAME_POS]; /* relative position (0-1) between lpskr pair (currently) associated with input chan */
  1280. /* NB same VALUE for ALL input chans, but output-lspkr-pair different for each input chan */
  1281. double *step = dz->parray[FRAME_STEP]; /* change in relative-position between lspkr-pair */
  1282. double *llevel = dz->parray[FRAME_LLEVEL]; /* level on 'left' lpskr of pair, to produce apparent motion */
  1283. double *rlevel = dz->parray[FRAME_RLEVEL]; /* level on 'right' lpskr of pair, to produce apparent motion */
  1284. int *orient = dz->lparray[FRAME_ORIENT]; /* first non-zero motion; either clock or anticlock */
  1285. int *ochan_left = dz->lparray[FRAME_OCHAN_LEFT]; /* 'left' lspkr of output-lspkr pair currently associated with specific input-channel */
  1286. int *ochan_right = dz->lparray[FRAME_OCHAN_RIGHT]; /* 'right' lspkr of output-lspkr pair currently associated with specific input-channel */
  1287. int *ol = dz->lparray[FRAME_OL]; /* 'left' lspkr of output-lspkr pair once 'snaking' is factored in */
  1288. int *or = dz->lparray[FRAME_OR]; /* 'right' lspkr of output-lspkr pair once 'snaking' is factored in */
  1289. int *snakeperm = dz->lparray[FRAME_SNAKEPERM]; /* Current snaking-path */
  1290. int insampcnt, bufpos, inhere, outhere;
  1291. float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1];
  1292. double lsig, rsig; /* input signal sent to 'left' and to 'right' lspkrs at current out-location. */
  1293. double smearcompensate = 1.0; /* Reduction in principle dignal to allow for sigs from adjacent chans been smeared into it. */
  1294. if(dz->param[SMEAR] > 0.0)
  1295. smearcompensate = 1 - (2.0 * dz->param[SMEAR]);
  1296. time = 0.0;
  1297. click = (int)round(srate/(double)MAX_ROT) * chans; /* Timestep between each reading of rotation-speed brktables */
  1298. /* ESTABLISH VALUE OF FIRST SPATIAL STEP, AND ORIENTATION OF FIRST MOTION (clock or anticlock) */
  1299. if((exit_status = read_values_from_all_existing_brktables(0.0,dz))<0)
  1300. return(exit_status);
  1301. step[0] = (dz->param[ROTATION0]/srate) * chans;
  1302. orient[0] = get_first_rotation_orientation(0,dz);
  1303. if(dz->mode == 1) {
  1304. step[1] = (dz->param[ROTATION1]/srate) * chans;
  1305. orient[1] = get_first_rotation_orientation(1,dz);
  1306. if((orient[0] == 0) && (orient[1] == 0)) {
  1307. sprintf(errstr,"No rotations specified (rotation speeds always zero)\n");
  1308. return(DATA_ERROR);
  1309. }
  1310. out_lspkr_step = 2; /* motions are only from an even lspkr to another even lpskr, or from an odd lspkr to another odd lspkr */
  1311. } else {
  1312. out_lspkr_step = 1; /* motion moves from one lspkr to any other */
  1313. }
  1314. /* IF THERE IS SNAKING, SETUP FIRST SNAKING-ROUTE */
  1315. if(dz->itemcnt) {
  1316. dz->next_snake_loc = 0;
  1317. get_next_snake(dz);
  1318. }
  1319. /* ESTABLISH CHANNEL-PAIRS BETWEEN WHICH INPUT-CHANNELS MOVE, INITIALLY, AND ESTABLISH INITIAL INTER-SPEAKER POSITION */
  1320. if(dz->mode == 0) {
  1321. if(orient[0] >= 0) { /* clockwise */
  1322. for(n=0;n<chans;n++) {
  1323. ochan_left[n] = n; /* output channel starts at location of input chan */
  1324. ol[n] = ochan_left[n];
  1325. ochan_right[n] = (n+out_lspkr_step) % chans; /*input chans will move rightwards to adjacent output channel */
  1326. or[n] = ochan_right[n];
  1327. if(dz->itemcnt) /* If there is snaking, 'adjacency' is redefined by the snaking-path */
  1328. or[n] = (int)snakeperm[or[n]];
  1329. }
  1330. inter_lspkr_position[0] = -step[0]; /* Offset to left at start, so when algo starts to run by stepping to right, it's set back to initial position at 0 */
  1331. } else { /* anticlockwise */
  1332. for(n=0;n<chans;n++) {
  1333. ochan_right[n] = n; /* output channel starts at location of input chan */
  1334. or[n] = ochan_right[n];
  1335. ochan_left[n] = n - out_lspkr_step; /*input chans will move leftwards to adjacent output channel */
  1336. if(ochan_left[n] < 0)
  1337. ochan_left[n] += chans;
  1338. ol[n] = ochan_left[n];
  1339. if(dz->itemcnt) /* If there is snaking, 'adjacency' is redefined by the snaking-path */
  1340. ol[n] = (int)snakeperm[ol[n]];
  1341. }
  1342. inter_lspkr_position[0] = step[0]; /* Offset to right at start, so when algo starts to run by stepping to left, it's set back to initial position at 0 */
  1343. }
  1344. } else {
  1345. if(orient[0] > 0) {
  1346. for(n=0;n<chans;n+=2) { /* EVEN lspkrs only */
  1347. ochan_left[n] = n;
  1348. ol[n] = ochan_left[n];
  1349. ochan_right[n] = (n+out_lspkr_step) % chans;
  1350. or[n] = ochan_right[n];
  1351. if(dz->itemcnt)
  1352. or[n] = (int)snakeperm[or[n]];
  1353. }
  1354. inter_lspkr_position[0] = -step[0];
  1355. } else {
  1356. for(n=0;n<chans;n+=2) {
  1357. ochan_right[n] = n;
  1358. or[n] = ochan_right[n];
  1359. ochan_left[n] = n - out_lspkr_step;
  1360. if(ochan_left[n] < 0)
  1361. ochan_left[n] += chans;
  1362. ol[n] = ochan_left[n];
  1363. if(dz->itemcnt)
  1364. ol[n] = (int)snakeperm[ol[n]];
  1365. }
  1366. inter_lspkr_position[0] = step[0];
  1367. }
  1368. if(orient[1] > 0) {
  1369. for(n=1;n<chans;n+=2) { /* ODD lspkrs only */
  1370. ochan_left[n] = n;
  1371. ol[n] = ochan_left[n];
  1372. ochan_right[n] = (n+out_lspkr_step) % chans;
  1373. or[n] = ochan_right[n];
  1374. if(dz->itemcnt)
  1375. or[n] = (int)snakeperm[or[n]];
  1376. }
  1377. inter_lspkr_position[1] = -step[1];
  1378. } else {
  1379. for(n=1;n<chans;n+=2) {
  1380. ochan_right[n] = n;
  1381. or[n] = ochan_right[n];
  1382. ochan_left[n] = n - out_lspkr_step;
  1383. if(ochan_left[n] < 0)
  1384. ochan_left[n] += chans;
  1385. ol[n] = ochan_left[n];
  1386. if(dz->itemcnt)
  1387. ol[n] = (int)snakeperm[ol[n]];
  1388. }
  1389. inter_lspkr_position[1] = step[1];
  1390. }
  1391. }
  1392. nextclick = click; /* Establish next time at which to read any rotation brkpnt data */
  1393. insampcnt = 0;
  1394. bufpos = 0;
  1395. if((exit_status = read_samps(ibuf,dz))<0) /* buflen is automatically a multipler of input channel count. */
  1396. return(exit_status);
  1397. memset((char *)obuf,0,dz->buflen * sizeof(float)); /* set obuf to zero, as values are ADDED into it */
  1398. /* OUTER LOOP - PROCESS ENTIRE INPUT FILE TO OUTPUT */
  1399. while(insampcnt < dz->insams[0]) {
  1400. /* INNER LOOP - PROCESS FILE UP TO NEXT POTENTIAL ROTATION-BREAKPOINT READ */
  1401. while(insampcnt < nextclick) {
  1402. if(insampcnt >= dz->insams[0])
  1403. break;
  1404. inter_lspkr_position[0] += step[0]; /* Find next spatial location */
  1405. /* IF inter-speaker position goes outside current lspkr pair, change to next loudpseaker pair, and readjust position to 0-1 range */
  1406. if(dz->mode == 0) {
  1407. if(inter_lspkr_position[0] < 0.0 || inter_lspkr_position[0] > 1.0) {
  1408. if(inter_lspkr_position[0] > 1.0) {
  1409. for(n=0;n<chans;n++) {
  1410. ochan_left[n] = ochan_right[n];
  1411. ol[n] = ochan_left[n];
  1412. ochan_right[n] = (ochan_right[n] + out_lspkr_step) % chans;
  1413. or[n] = ochan_right[n];
  1414. }
  1415. inter_lspkr_position[0] -= 1.0;
  1416. } else {
  1417. for(n=0;n<chans;n++) {
  1418. ochan_right[n] = ochan_left[n];
  1419. or[n] = ochan_right[n];
  1420. ochan_left[n] = ochan_left[n] - out_lspkr_step;
  1421. if(ochan_left[n] < 0)
  1422. ochan_left[n] += chans;
  1423. ol[n] = ochan_left[n];
  1424. }
  1425. inter_lspkr_position[0] += 1.0;
  1426. }
  1427. if(dz->itemcnt) { /* if snaking, redefine 'adjaceny' */
  1428. for(n=0;n<chans;n++) {
  1429. or[n] = (int)snakeperm[or[n]];
  1430. ol[n] = (int)snakeperm[ol[n]];
  1431. }
  1432. }
  1433. }
  1434. } else {
  1435. inter_lspkr_position[1] += step[1]; /* Find next spatial location in 2nd rotation, too*/
  1436. if(inter_lspkr_position[0] < 0.0 || inter_lspkr_position[0] > 1.0) {
  1437. if(inter_lspkr_position[0] > 1.0) {
  1438. for(n=0;n<chans;n+=2) { /* EVEN lpskrs only, NB */
  1439. ochan_left[n] = ochan_right[n];
  1440. ol[n] = ochan_left[n];
  1441. ochan_right[n] = (ochan_right[n] + out_lspkr_step) % chans;
  1442. or[n] = ochan_right[n];
  1443. }
  1444. inter_lspkr_position[0] -= 1.0;
  1445. } else {
  1446. for(n=0;n<chans;n+=2) {
  1447. ochan_right[n] = ochan_left[n];
  1448. or[n] = ochan_right[n];
  1449. ochan_left[n] = ochan_left[n] - out_lspkr_step;
  1450. if(ochan_left[n] < 0)
  1451. ochan_left[n] += chans;
  1452. ol[n] = ochan_left[n];
  1453. }
  1454. inter_lspkr_position[0] += 1.0;
  1455. }
  1456. if(dz->itemcnt) { /* if snaking, redefine 'adjaceny' */
  1457. for(n=0;n<chans;n+=2) {
  1458. or[n] = (int)snakeperm[or[n]];
  1459. ol[n] = (int)snakeperm[ol[n]];
  1460. }
  1461. }
  1462. }
  1463. if(inter_lspkr_position[1] < 0.0 || inter_lspkr_position[1] > 1.0) {
  1464. if(inter_lspkr_position[1] > 1.0) {
  1465. for(n=1;n<chans;n+=2) { /* ODD lpskrs only, NB */
  1466. ochan_left[n] = ochan_right[n];
  1467. ol[n] = ochan_left[n];
  1468. ochan_right[n] = (ochan_right[n] + out_lspkr_step) % chans;
  1469. or[n] = ochan_right[n];
  1470. }
  1471. inter_lspkr_position[1] -= 1.0;
  1472. } else {
  1473. for(n=1;n<chans;n+=2) {
  1474. ochan_right[n] = ochan_left[n];
  1475. or[n] = ochan_right[n];
  1476. ochan_left[n] = ochan_left[n] - out_lspkr_step;
  1477. if(ochan_left[n] < 0)
  1478. ochan_left[n] += chans;
  1479. ol[n] = ochan_left[n];
  1480. }
  1481. inter_lspkr_position[1] += 1.0;
  1482. }
  1483. if(dz->itemcnt) { /* if snaking, redefine 'adjaceny' */
  1484. for(n=1;n<chans;n+=2) {
  1485. or[n] = (int)snakeperm[or[n]];
  1486. ol[n] = (int)snakeperm[ol[n]];
  1487. }
  1488. }
  1489. }
  1490. }
  1491. /* SET RELATIVE LEVELS ON (every) LOUDSPEAKER PAIR, FROM POSITION INFO */
  1492. set_stereo_levels(inter_lspkr_position[0],&(llevel[0]),&(rlevel[0]));
  1493. if(dz->mode == 1)
  1494. set_stereo_levels(inter_lspkr_position[1],&(llevel[1]),&(rlevel[1]));
  1495. /* CALCULATE THE OUTPUT SUMMED FROM EVERY INPUT CHAN */
  1496. if(dz->mode == 0) {
  1497. for(n=0;n<chans;n++) {
  1498. inhere = bufpos + n; /* location of input sample is offset by 'n' to find the correct channel */
  1499. outhere = bufpos + ol[n]; /* location of output to related 'left' lspkr is offset similarly to correct channel */
  1500. lsig = llevel[0] * ibuf[inhere] * smearcompensate;
  1501. obuf[outhere] = (float)(obuf[outhere] + lsig);
  1502. outhere = bufpos + or[n]; /* location of output to related 'right' lspkr is offset similarly to correct channel */
  1503. rsig = rlevel[0] * ibuf[inhere] * smearcompensate;
  1504. obuf[outhere] = (float)(obuf[outhere] + rsig);
  1505. if(dz->param[SMEAR] > 0.0)
  1506. do_smear(ol[n],or[n],lsig,rsig,bufpos,chans,obuf,dz->param[SMEAR]);
  1507. }
  1508. } else {
  1509. for(n=0;n<chans;n+=2) { /* EVEN chans only */
  1510. inhere = bufpos + n;
  1511. outhere = bufpos + ol[n];
  1512. lsig = llevel[0] * ibuf[inhere] * smearcompensate;
  1513. obuf[outhere] = (float)(obuf[outhere] + lsig);
  1514. outhere = bufpos + or[n];
  1515. rsig = rlevel[0] * ibuf[inhere] * smearcompensate;
  1516. obuf[outhere] = (float)(obuf[outhere] + rsig);
  1517. if(dz->param[SMEAR] > 0.0)
  1518. do_smear(ol[n],or[n],lsig,rsig,bufpos,chans,obuf,dz->param[SMEAR]);
  1519. }
  1520. for(n=1;n<chans;n+=2) { /* ODD chans only */
  1521. inhere = bufpos + n;
  1522. outhere = bufpos + ol[n];
  1523. lsig = llevel[1] * ibuf[inhere] * smearcompensate;
  1524. obuf[outhere] = (float)(obuf[outhere] + lsig);
  1525. outhere = bufpos + or[n];
  1526. rsig = rlevel[1] * ibuf[inhere] * smearcompensate;
  1527. obuf[outhere] = (float)(obuf[outhere] + rsig);
  1528. if(dz->param[SMEAR] > 0.0)
  1529. do_smear(ol[n],or[n],lsig,rsig,bufpos,chans,obuf,dz->param[SMEAR]);
  1530. }
  1531. }
  1532. insampcnt += chans; /* step to next group-sample of input */
  1533. bufpos += chans;
  1534. /* once whole buffer is processed, write output, and read new input */
  1535. if(bufpos >= dz->ssampsread) {
  1536. if((exit_status = write_samps(obuf,dz->ssampsread,dz))<0)
  1537. return(exit_status);
  1538. memset((char *)obuf,0,dz->buflen * sizeof(float));
  1539. if((exit_status = read_samps(ibuf,dz))<0)
  1540. return(exit_status);
  1541. if(dz->ssampsread == 0)
  1542. break;
  1543. bufpos = 0;
  1544. }
  1545. /* IF MORE SNAKE DATA, IF IT'S TIME TO READ IT, READ IT */
  1546. if(dz->next_snake_time && (insampcnt >= dz->next_snake_time))
  1547. get_next_snake(dz);
  1548. }
  1549. /* ON REACHING NEXT POTENTIAL ROTATION-BRKPOINT, READ ROTATION-SPEED VALUE */
  1550. time = (double)(insampcnt/chans)/srate;
  1551. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  1552. return(exit_status);
  1553. step[0] = (dz->param[ROTATION0]/srate) * chans;
  1554. if(dz->mode == 1)
  1555. step[1] = (dz->param[ROTATION1]/srate) * chans;
  1556. nextclick += click; /* Set next (sample)time at which to read rotation-speed */
  1557. }
  1558. if(bufpos > 0) {
  1559. if((exit_status = write_samps(obuf,bufpos,dz))<0)
  1560. return(exit_status);
  1561. }
  1562. return(FINISHED);
  1563. }
  1564. /************************************************** GET_NEXT_SNAKE **************************************************/
  1565. void get_next_snake(dataptr dz)
  1566. {
  1567. int entrylen = dz->infile->channels + 1;
  1568. int k = dz->next_snake_loc + 1, n;
  1569. for(n=0;n < dz->infile->channels;n++) {
  1570. dz->lparray[FRAME_SNAKEPERM][n] = dz->lparray[FRAME_SNAKE][k];
  1571. k++;
  1572. }
  1573. dz->next_snake_loc += entrylen;
  1574. if(dz->next_snake_loc < dz->itemcnt)
  1575. dz->next_snake_time = dz->lparray[FRAME_SNAKE][dz->next_snake_loc]; /* time(in samples) of start of next snake data */
  1576. else
  1577. dz->next_snake_time = 0; /* flags, no more snakes */
  1578. }
  1579. /************************** GET_FIRST_ROTATION_ORIENTATION ********************************/
  1580. int get_first_rotation_orientation(int n,dataptr dz)
  1581. {
  1582. int j;
  1583. if(dz->brksize[n] == 0) {
  1584. if(dz->param[n] == 0.0) /* no rotation */
  1585. return 0;
  1586. else if(dz->param[n] > 0.0) /* clockwise rotation */
  1587. return 1;
  1588. return -1; /* anticlockwise rotation */
  1589. }
  1590. for(j=1;j<dz->brksize[n];j+=2) {
  1591. if(dz->brk[n][j] > 0.0) /* first rotation is clockwise */
  1592. return 1;
  1593. if(dz->brk[n][j] < 0.0) /* first rotation is anticlockwise */
  1594. return -1;
  1595. }
  1596. return 0; /* no (non-zero) rotation found */
  1597. }
  1598. /************************** READ_THE_SPECIAL_DATA ********************************/
  1599. int read_the_special_data(char *filename,dataptr dz)
  1600. {
  1601. int exit_status, entrylen=0, linecnt, ival;
  1602. int n = 0, k, chans = dz->infile->channels;
  1603. double time, lasttime, val;
  1604. char temp[200], *p, *thisword, temp2[200];
  1605. thisword = temp2;
  1606. p = filename;
  1607. if((sloom && *p == '@') || (!sloom && isdigit(*p))) {
  1608. switch(dz->mode) {
  1609. case(2):
  1610. sprintf(errstr,"Data must be in a file\n");
  1611. return(DATA_ERROR);
  1612. case(6):
  1613. if(sloom)
  1614. p++;
  1615. if((sscanf(p,"%d",&n)) < 1) {
  1616. sprintf(errstr,"No such channel (%s) in the input file.\n",p);
  1617. return(DATA_ERROR);
  1618. }
  1619. if((n < 1) || (n > dz->infile->channels)) {
  1620. sprintf(errstr,"No such channel (%d) in the input file.\n",n);
  1621. return(DATA_ERROR);
  1622. }
  1623. if((dz->lparray[0] = malloc(sizeof(int)))==NULL) {
  1624. sprintf(errstr,"Insufficient memory to store chans-to-process info.\n");
  1625. return(MEMORY_ERROR);
  1626. }
  1627. dz->lparray[0][0] = n - 1; // Convert to 0 to N-1 frame
  1628. dz->itemcnt = 1;
  1629. return FINISHED;
  1630. default:
  1631. dz->itemcnt = 0; /* flags 'no snake data' */
  1632. dz->next_snake_time = 0; /* flags 'no more snake data' */
  1633. return FINISHED;
  1634. }
  1635. }
  1636. if((dz->fp = fopen(filename,"r"))==NULL) {
  1637. sprintf(errstr,"Cannot open datafile %s\n",filename);
  1638. return(DATA_ERROR);
  1639. }
  1640. while(fgets(temp,200,dz->fp)!=NULL) {
  1641. p = temp;
  1642. if(is_an_empty_line_or_a_comment(p))
  1643. continue;
  1644. while(get_word_from_string(&p,&thisword))
  1645. n++;
  1646. }
  1647. if(n==0) {
  1648. sprintf(errstr,"No data in file %s\n",filename);
  1649. return(DATA_ERROR);
  1650. }
  1651. dz->itemcnt = n;
  1652. switch(dz->mode) {
  1653. case(2):
  1654. entrylen = chans; // reorientation
  1655. if(n != entrylen) {
  1656. sprintf(errstr,"Reorient data in file %s is in incorrect format.\n",filename);
  1657. return(DATA_ERROR);
  1658. }
  1659. if((dz->lparray[FRAME_SNAKE] = malloc(dz->itemcnt * sizeof(int)))==NULL) {
  1660. sprintf(errstr,"Insufficient memory to store reorient data from file %s.\n",filename);
  1661. return(MEMORY_ERROR);
  1662. }
  1663. break;
  1664. case(0):
  1665. case(1):
  1666. entrylen = chans + 1; // time-variable rotation-snake
  1667. k = n % entrylen;
  1668. if(k != 0) {
  1669. sprintf(errstr,"Snake data in file %s is in incorrect format.\n",filename);
  1670. return(DATA_ERROR);
  1671. }
  1672. if((dz->lparray[FRAME_SNAKE] = malloc(dz->itemcnt * sizeof(int)))==NULL) {
  1673. sprintf(errstr,"Insufficient memory to store snaking data from file %s.\n",filename);
  1674. return(MEMORY_ERROR);
  1675. }
  1676. break;
  1677. case(6):
  1678. if((dz->lparray[0] = malloc((dz->itemcnt + 4) * sizeof(int)))==NULL) {
  1679. sprintf(errstr,"Insufficient memory to store edit-chans data in file %s.\n",filename);
  1680. return(MEMORY_ERROR);
  1681. }
  1682. break;
  1683. }
  1684. if(fseek(dz->fp,0,0)<0) {
  1685. sprintf(errstr,"fseek() failed in read_the_special_data()\n");
  1686. return(SYSTEM_ERROR);
  1687. }
  1688. n = 0;
  1689. linecnt = 1;
  1690. lasttime = 0.0;
  1691. while(fgets(temp,200,dz->fp)!=NULL) {
  1692. p = temp;
  1693. if(is_an_empty_line_or_a_comment(temp))
  1694. continue;
  1695. while(get_word_from_string(&p,&thisword)) {
  1696. switch(dz->mode) {
  1697. case(0):
  1698. case(1):
  1699. if(n % entrylen == 0) {
  1700. if(sscanf(thisword,"%lf",&time)!=1) {
  1701. sprintf(errstr,"Problem reading Time: line %d: file %s\n",linecnt,filename);
  1702. return(DATA_ERROR);
  1703. }
  1704. if(n == 0) {
  1705. if(time != 0.0) {
  1706. sprintf(errstr,"First time is not zero in file %s\n",filename);
  1707. return(DATA_ERROR);
  1708. }
  1709. } else {
  1710. if(time <= lasttime) {
  1711. sprintf(errstr,"Time does not advance at line %d in file %s\n",linecnt,filename);
  1712. return(DATA_ERROR);
  1713. }
  1714. /* TEST SNAKE VALIDITY in last set of 'chans' values */
  1715. if((exit_status = snake_test(n,lasttime,linecnt-1,filename,dz)) < 0)
  1716. return(exit_status);
  1717. lasttime = time;
  1718. }
  1719. dz->lparray[FRAME_SNAKE][n] = (int)round(time * dz->infile->srate) * chans;
  1720. } else {
  1721. if(sscanf(thisword,"%lf",&val)!=1) {
  1722. sprintf(errstr,"Problem reading Value: line %d: file %s\n",linecnt,filename);
  1723. return(DATA_ERROR);
  1724. }
  1725. ival = (int)round(val);
  1726. if(ival < 1 || ival > chans) {
  1727. sprintf(errstr,"Invalid channel number (%d) in file %s : line %d\n",ival,filename,linecnt);
  1728. return(DATA_ERROR);
  1729. }
  1730. ival--;
  1731. dz->lparray[FRAME_SNAKE][n] = ival;
  1732. }
  1733. break;
  1734. case(2):
  1735. if(sscanf(thisword,"%lf",&val)!=1) {
  1736. sprintf(errstr,"Problem reading Value: file %s\n",filename);
  1737. return(DATA_ERROR);
  1738. }
  1739. ival = (int)round(val);
  1740. if(ival < 1 || ival > chans) {
  1741. sprintf(errstr,"Invalid channel number (%d) in file %s\n",ival,filename);
  1742. return(DATA_ERROR);
  1743. }
  1744. ival--;
  1745. dz->lparray[FRAME_SNAKE][n] = ival;
  1746. break;
  1747. case(6):
  1748. if(sscanf(thisword,"%lf",&val)!=1) {
  1749. sprintf(errstr,"Problem reading Value: file %s\n",filename);
  1750. return(DATA_ERROR);
  1751. }
  1752. ival = (int)round(val);
  1753. if(ival < 1 || ival > chans) {
  1754. sprintf(errstr,"Invalid channel number (%d) in file %s\n",ival,filename);
  1755. return(DATA_ERROR);
  1756. }
  1757. ival--;
  1758. dz->lparray[0][n] = ival;
  1759. break;
  1760. }
  1761. n++;
  1762. }
  1763. linecnt++;
  1764. }
  1765. if(fclose(dz->fp)<0) {
  1766. fprintf(stdout,"WARNING: Failed to close input textfile %s.\n",filename);
  1767. fflush(stdout);
  1768. }
  1769. switch(dz->mode) {
  1770. case(2):
  1771. if((exit_status = reorient_test(dz)) < 0) /* Test reorientation entries */
  1772. return(exit_status);
  1773. break;
  1774. case(6):
  1775. if((exit_status = editchans_test(dz)) < 0) /* Test edit-chans entries */
  1776. return(exit_status);
  1777. break;
  1778. default:
  1779. if((exit_status = snake_test(n,lasttime,linecnt-1,filename,dz)) < 0) /* Test final set of snake entries */
  1780. return(exit_status);
  1781. break;
  1782. }
  1783. return(FINISHED);
  1784. }
  1785. /************************************************ SNAKE_TEST *****************************************/
  1786. int snake_test(int n,double lasttime,int linecnt,char *filename,dataptr dz)
  1787. {
  1788. int m, j, k;
  1789. int chans = dz->infile->channels;
  1790. m = n - chans;
  1791. for(k = m; k < n-1; k++) {
  1792. for(j = k + 1; j < n; j++) {
  1793. if(dz->lparray[FRAME_SNAKE][k] == dz->lparray[FRAME_SNAKE][j]) {
  1794. sprintf(errstr,"Invalid snake sequence: file %s time %lf line %d: (channel %d repeated)\n",filename,lasttime,linecnt,dz->lparray[FRAME_SNAKE][k]);
  1795. return(DATA_ERROR);
  1796. }
  1797. }
  1798. }
  1799. return(FINISHED);
  1800. }
  1801. /************************************************ SET_STEREO_LEVELS *****************************************/
  1802. void set_stereo_levels(double pos, double *llevel, double *rlevel)
  1803. {
  1804. double relpos, temp, holecompensate;
  1805. double zerocentredposition = (pos * 2.0) - 1.0; /* range -1 to 1 */
  1806. if(zerocentredposition < 0)
  1807. relpos = -zerocentredposition; /* range 0 to 1 : position relative to centre of stereo */
  1808. else
  1809. relpos = zerocentredposition;
  1810. temp = 1.0 + (relpos * relpos); /* calculate hole in middle compensation */
  1811. holecompensate = ROOT2 / sqrt(temp);
  1812. *rlevel = pos * holecompensate;
  1813. *llevel = (1.0 - pos) * holecompensate;
  1814. }
  1815. /************************************************ DO_SMEAR *****************************************/
  1816. void do_smear(int loutchan,int routchan,double lsig,double rsig,int bufpos,int chans,float *obuf,double smear)
  1817. {
  1818. int smearleft, smearright;
  1819. // smear left output chan to its own left and right
  1820. if((smearleft = loutchan - 1) < 0)
  1821. smearleft += chans;
  1822. if((smearright = loutchan + 1) >= chans)
  1823. smearright -= chans;
  1824. smearleft += bufpos;
  1825. smearright += bufpos;
  1826. obuf[smearleft] = (float)(obuf[smearleft] + (lsig * smear));
  1827. obuf[smearright] = (float)(obuf[smearright] + (lsig * smear));
  1828. // smear right output chan to its own left and right
  1829. if((smearleft = routchan - 1) < 0)
  1830. smearleft += chans;
  1831. smearleft += bufpos;
  1832. if((smearright = routchan + 1) >= chans)
  1833. smearright -= chans;
  1834. smearright += bufpos;
  1835. obuf[smearleft] = (float)(obuf[smearleft] + (rsig * smear));
  1836. obuf[smearright] = (float)(obuf[smearright] + (rsig * smear));
  1837. }
  1838. /************************************************ REORIENT *****************************************/
  1839. int reorient(dataptr dz)
  1840. {
  1841. int exit_status, chans = dz->infile->channels;
  1842. float *ibuf = dz->sampbuf[0];
  1843. float *obuf = dz->sampbuf[1];
  1844. int *ochan = dz->lparray[FRAME_SNAKE];
  1845. int n, m;
  1846. while(dz->samps_left) {
  1847. if((exit_status = read_samps(ibuf,dz))<0)
  1848. return(exit_status);
  1849. for(n=0;n < dz->ssampsread;n+=chans) {
  1850. for(m=0;m <chans;m++)
  1851. obuf[ochan[m]+n] = ibuf[m+n];
  1852. }
  1853. if((exit_status = write_samps(obuf,dz->ssampsread,dz))<0)
  1854. return(exit_status);
  1855. }
  1856. return(FINISHED);
  1857. }
  1858. /************************************************ REORIENT_TEST *****************************************/
  1859. int reorient_test(dataptr dz)
  1860. {
  1861. int chans = dz->infile->channels;
  1862. int *ochan = dz->lparray[FRAME_SNAKE];
  1863. int n, m;
  1864. for(n=0;n<chans-1;n++) {
  1865. if(ochan[n] >= chans) {
  1866. sprintf(errstr,"Invalid Channel (%d) in reorientation data\n",ochan[n]+1);
  1867. return(DATA_ERROR);
  1868. }
  1869. for(m=n+1;m<chans;m++) {
  1870. if(ochan[n] == ochan[m]) {
  1871. sprintf(errstr,"Duplicated Channel (%d) in reorientation data\n",ochan[n]+1);
  1872. return(DATA_ERROR);
  1873. }
  1874. }
  1875. }
  1876. if(ochan[n] >= chans) {
  1877. sprintf(errstr,"Invalid Channel (%d) in reorientation data\n",ochan[n]+1);
  1878. return(DATA_ERROR);
  1879. }
  1880. return FINISHED;
  1881. }
  1882. /************************************************ EDITCHANS_TEST *****************************************/
  1883. int editchans_test(dataptr dz)
  1884. {
  1885. int *echan = dz->lparray[0];
  1886. int n, m;
  1887. for(n=0;n<dz->itemcnt-1;n++) {
  1888. for(m=n+1;m<dz->itemcnt;m++) {
  1889. if(echan[n] == echan[m]) {
  1890. sprintf(errstr,"repeated channel (%d) in channel edit data\n",echan[n]+1);
  1891. return(DATA_ERROR);
  1892. }
  1893. }
  1894. }
  1895. return FINISHED;
  1896. }
  1897. /************************************ CHECK_THE_PARAM_VALIDITY_AND_CONSISTENCY ****************************/
  1898. int check_the_param_validity_and_consistency(dataptr dz)
  1899. {
  1900. int exit_status, k;
  1901. double frac;
  1902. switch(dz->mode) {
  1903. case(3):
  1904. k = (int)floor(dz->param[0]);
  1905. if(k > dz->infile->channels) {
  1906. sprintf(errstr,"Mirrorplane (%.1lf) not compatible with channel count (%d)\n",dz->param[0],dz->infile->channels);
  1907. return(DATA_ERROR);
  1908. }
  1909. if(k != dz->param[0]) {
  1910. frac = dz->param[0] - (double)k;
  1911. if(!flteq(frac,0.5)) {
  1912. sprintf(errstr,"Mirrorplane value must an be integers or a half-integer (e.g. 1.5, 3.5)\n");
  1913. return(DATA_ERROR);
  1914. }
  1915. }
  1916. if((exit_status = mirror(dz))<0)
  1917. return(exit_status);
  1918. break;
  1919. case(4):
  1920. if((exit_status = bilateral(dz))<0)
  1921. return(exit_status);
  1922. break;
  1923. case(7):
  1924. if((exit_status = beast_bilateral(dz))<0)
  1925. return(exit_status);
  1926. break;
  1927. case(5):
  1928. if(dz->iparam[0] > dz->infile->channels) {
  1929. sprintf(errstr,"Channel %d does not exist in input file.\n",dz->iparam[0]);
  1930. return(DATA_ERROR);
  1931. }
  1932. if(dz->iparam[1] > dz->infile->channels) {
  1933. sprintf(errstr,"Channel %d does not exist in input file.\n",dz->iparam[1]);
  1934. return(DATA_ERROR);
  1935. }
  1936. if(dz->iparam[0] == dz->iparam[1]) {
  1937. sprintf(errstr,"Can't swap channel %d with itself\n",dz->iparam[0]);
  1938. return(DATA_ERROR);
  1939. }
  1940. dz->iparam[0]--; // Change to 0 to N-1 frame
  1941. dz->iparam[1]--;
  1942. break;
  1943. }
  1944. return FINISHED;
  1945. }
  1946. /************************************ MIRROR ****************************/
  1947. int mirror(dataptr dz)
  1948. {
  1949. int mirrorplane, outchans = dz->infile->channels, ichan, ochan, lastchan, n;
  1950. int *mirrormap;
  1951. if((dz->lparray[FRAME_SNAKE] = malloc(outchans * sizeof(int)))==NULL) {
  1952. sprintf(errstr,"Insufficient memory to store mirroring data.\n");
  1953. return(MEMORY_ERROR);
  1954. }
  1955. mirrormap = dz->lparray[FRAME_SNAKE];
  1956. mirrorplane = (int)round(dz->param[0] * 2.0); // 2.0 maps to 4 2.5 maps to 5
  1957. if(EVEN(mirrorplane))
  1958. mirrorplane = (int)round(dz->param[0]); // 2.0 maps to 2
  1959. else
  1960. mirrorplane = -(mirrorplane/2); // 5 (2.5) maps to -2 : 7 (3.5) to -3 etc.
  1961. if(mirrorplane > 0) { // mirror centred in lspkr
  1962. mirrorplane--; // lspkrs are numbered 0 to (N-1)
  1963. for(n=0; n < outchans; n++) { // if mirrorplane is at zero
  1964. ichan = mirrorplane + n; // 0 1 2 3 4 5 6 7 OR 0 1 2 3 4 5 6
  1965. while(ichan >= outchans)
  1966. ichan -= outchans; // (even chancnt) GOES TO (odd chancnt) GOES TO
  1967. ochan = mirrorplane - n;
  1968. while(ochan < 0) // 0 -1 -2 -3 -4 -5 -6 -7 0 -1 -2 -3 -4 -5 -6
  1969. ochan += outchans; // = 0 7 6 5 4 3 2 1 = 0 6 5 4 3 2 1
  1970. mirrormap[ichan] = ochan;
  1971. }
  1972. } else { // mirror centred between lspkrs
  1973. mirrorplane = -mirrorplane; // -2 to 2 etc. mirror is between 2 & 3 of internal numbering (0 to (N-1))
  1974. mirrorplane--; // lspkrs are numbered 0 to (N-1)
  1975. // if mirrorplane is at 0.5, (mirrorplane value here 0)
  1976. if(EVEN(outchans)) { // originally 1.5: ABOVE: doubled = 3 : to -(N/2)= -1: HERE to -N = 1: to decr = 0)
  1977. for(n=1; n <= outchans; n++) { // 1 2 3 4 5 6 7 8
  1978. ichan = mirrorplane + n; // = 1 2 3 4 5 6 7 0
  1979. while(ichan >= outchans)
  1980. ichan -= outchans; // (even chancnt) GOES TO
  1981. ochan = mirrorplane - n + 1;
  1982. while(ochan < 0) // 0 -1 -2 -3 -4 -5 -6 -7
  1983. ochan += outchans; // = 0 7 6 5 4 3 2 1
  1984. mirrormap[ichan] = ochan;
  1985. }
  1986. } else {
  1987. lastchan = outchans/2; // for 7, lastchan = 3
  1988. lastchan++; // for 7, lastchan = 4
  1989. for(n=1; n <= lastchan; n++) { // if mirrorplane is at 0.5
  1990. ichan = mirrorplane + n; // 1 2 3 4
  1991. while(ichan >= outchans)
  1992. ichan -= outchans; // (odd chancnt) GOES TO
  1993. ochan = mirrorplane - n + 1;
  1994. while(ochan < 0) // 0 -1 -2 -3
  1995. ochan += outchans; // =0 6 5 4
  1996. mirrormap[ichan] = ochan;
  1997. mirrormap[ochan] = ichan; // and vice versa
  1998. }
  1999. }
  2000. }
  2001. return(FINISHED);
  2002. }
  2003. /************************************ BILATERAL ************************/
  2004. int bilateral(dataptr dz)
  2005. {
  2006. int outchans = dz->infile->channels, ichan, ochan, split;
  2007. int *bi;
  2008. int toring = dz->vflag[0];
  2009. if((dz->lparray[FRAME_SNAKE] = malloc(outchans * sizeof(int)))==NULL) {
  2010. sprintf(errstr,"Insufficient memory to store bilateralisation data.\n");
  2011. return(MEMORY_ERROR);
  2012. }
  2013. bi = dz->lparray[FRAME_SNAKE];
  2014. split = (int)ceil((double)outchans/2.0); // 8 --> 4 7 --> 4
  2015. ichan = outchans - 1;
  2016. ochan = 1;
  2017. while(ichan >= split) { // with 8 (even no) chans with 7 (odd no) chans
  2018. if(toring) // 7 6 5 4 OR 6 5 4
  2019. bi[ochan] = ichan; // GOES TO GOES TO
  2020. else // 1 3 5 7 1 3 5
  2021. bi[ichan] = ochan;
  2022. ichan--;
  2023. ochan += 2;
  2024. }
  2025. while (ichan >= 0) { // with 8 (even no) chans with 7 (odd no) chans
  2026. if(toring) // 3 2 1 0 OR 3 2 1 0
  2027. bi[ichan * 2] = ichan; // GOES TO GOES TO
  2028. else // 6 4 2 0 6 4 2 0
  2029. bi[ichan] = ichan * 2;
  2030. ichan--;
  2031. }
  2032. return(FINISHED); // 0 0 0 0
  2033. } // 7 1 1 2 6 1 1 2
  2034. // 6 2 TO 3 4 5 2 TO 3 4
  2035. // 5 3 5 6 4 3 5 6
  2036. // 4 7
  2037. /************************************ BEAST_BILATERAL ************************/
  2038. int beast_bilateral(dataptr dz)
  2039. {
  2040. int outchans = dz->infile->channels, ichan, ochan;
  2041. int *bi;
  2042. int toring = dz->vflag[0], even, lastevenchanno, lastoddchanno = 0, limit;
  2043. if((dz->lparray[FRAME_SNAKE] = malloc(outchans * sizeof(int)))==NULL) {
  2044. sprintf(errstr,"Insufficient memory to store bilateralisation data.\n");
  2045. return(MEMORY_ERROR);
  2046. }
  2047. bi = dz->lparray[FRAME_SNAKE];
  2048. even = 1;
  2049. if((outchans/2) * 2 != outchans) {
  2050. even = 0;
  2051. lastevenchanno = outchans - 1; // 6 for 7channel file
  2052. } else {
  2053. lastevenchanno = outchans - 2; // 6 for 8channel file
  2054. lastoddchanno = outchans - 1; // 7 for 8channel file
  2055. }
  2056. if(toring)
  2057. bi[lastevenchanno] = 0;
  2058. else
  2059. bi[0] = lastevenchanno; // 0(1) -->6(7)
  2060. if(even) {
  2061. if(toring)
  2062. bi[lastoddchanno] = outchans/2;
  2063. else
  2064. bi[outchans/2] = lastoddchanno; // 4(5) -->7(8) if even number of chans
  2065. }
  2066. limit = outchans/2; // for 8 chans, up to 4
  2067. if(!even)
  2068. limit++; // for 7 chans, up to 4
  2069. ichan = 1;
  2070. while(ichan < limit) {
  2071. if(toring)
  2072. bi[(ichan * 2) - 1] = ichan;
  2073. else
  2074. bi[ichan] = (ichan * 2) - 1; // 1->1 2->3 3->5 (= 2->2 3->4 4->6)
  2075. ichan++;
  2076. }
  2077. ochan = 0;
  2078. ichan = outchans - 1; // for 8chans 7, for 7chans 6
  2079. limit = outchans/2; // for 8 chans, down to >4, for 7 chans, down to >3
  2080. while(ichan > limit) {
  2081. if(toring)
  2082. bi[ochan] = ichan;
  2083. else
  2084. bi[ichan] = ochan; // 7->0 6->2 5->4 (= 8->1 7->3 6->5)
  2085. ichan--;
  2086. ochan += 2;
  2087. }
  2088. return(FINISHED); // 0 6 0 6
  2089. } // 7 1 0 1 6 1 0 1
  2090. // 6 2 TO 2 3 5 2 TO 2 3
  2091. // 5 3 4 5 4 3 4 5
  2092. // 4 7
  2093. /************************************ SWAPCHAN ************************/
  2094. int swapchans(dataptr dz)
  2095. {
  2096. int exit_status;
  2097. float *buf = dz->sampbuf[0], temp;
  2098. int n;
  2099. int ochans = dz->infile->channels;
  2100. int thischan = dz->iparam[0], thatchan = dz->iparam[1];
  2101. if((exit_status = read_samps(buf,dz))<0)
  2102. return(exit_status);
  2103. if(dz->ssampsread == 0) {
  2104. sprintf(errstr,"No data in input soundfile\n");
  2105. return(DATA_ERROR);
  2106. }
  2107. while(dz->ssampsread > 0) {
  2108. for(n=0;n<dz->ssampsread;n+=ochans) {
  2109. temp = buf[n + thischan];
  2110. buf[n + thischan] = buf[n + thatchan];
  2111. buf[n + thatchan] = temp;
  2112. }
  2113. if((exit_status = write_samps(buf,dz->ssampsread,dz))<0)
  2114. return(exit_status);
  2115. if((exit_status = read_samps(buf,dz))<0)
  2116. return(exit_status);
  2117. }
  2118. return FINISHED;
  2119. }
  2120. /************************************ ENVCHANS ************************/
  2121. int envchans(dataptr dz)
  2122. {
  2123. int exit_status;
  2124. float *buf = dz->sampbuf[0];
  2125. int n;
  2126. int ochans = dz->infile->channels, k, thisochan;
  2127. int *chaninfo = dz->lparray[0], chunksamptime;
  2128. double thisgain, nextgain=0, gainstep, timestep, gainincr;
  2129. int thistime, nexttime;
  2130. int thisbrk = 0, nextbrk = 2;
  2131. double *gainvals = NULL;
  2132. if(dz->brksize[0]) {
  2133. gainvals = dz->brk[0];
  2134. thistime = (int)round(gainvals[thisbrk] * (double)dz->infile->srate);
  2135. if(thistime > 0.0) {
  2136. nexttime = (int)round(gainvals[nextbrk] * (double)dz->infile->srate);
  2137. thisgain = gainvals[thisbrk+1];
  2138. nextgain = thisgain; // If before start of brktable, set gain to first val in table
  2139. gainincr = 0.0; // and gain-increment to 0
  2140. } else {
  2141. nexttime = (int)round(gainvals[nextbrk] * (double)dz->infile->srate);
  2142. thisgain = gainvals[thisbrk+1];
  2143. nextgain = gainvals[nextbrk+1];
  2144. gainstep = nextgain - thisgain;
  2145. timestep = nexttime - thistime;
  2146. gainincr = gainstep/(double)timestep;
  2147. thisbrk += 2;
  2148. nextbrk += 2;
  2149. }
  2150. } else {
  2151. thisgain = dz->param[0];
  2152. gainincr = 0.0;
  2153. nexttime = dz->insams[0] + 2; // i.e. larger than chunksamptime counter can reach
  2154. }
  2155. if((exit_status = read_samps(buf,dz))<0)
  2156. return(exit_status);
  2157. if(dz->ssampsread == 0) {
  2158. sprintf(errstr,"No data in input soundfile\n");
  2159. return(DATA_ERROR);
  2160. }
  2161. chunksamptime = 0;
  2162. while(dz->ssampsread > 0) {
  2163. for(n=0;n<dz->ssampsread;n+=ochans,chunksamptime++) {
  2164. if(chunksamptime >= nexttime) {
  2165. if(nextbrk < dz->brksize[0] * 2) {
  2166. thistime = nexttime;
  2167. thisgain = nextgain;
  2168. nexttime = (int)round(gainvals[nextbrk] * (double)dz->infile->srate);
  2169. nextgain = gainvals[nextbrk+1];
  2170. gainstep = nextgain - thisgain;
  2171. timestep = nexttime - thistime;
  2172. gainincr = gainstep/(double)timestep;
  2173. thisbrk += 2;
  2174. nextbrk += 2;
  2175. } else
  2176. gainincr = 0.0; // If run off end of brktable, keep gain steady
  2177. }
  2178. for(k = 0; k < dz->itemcnt;k++) {
  2179. thisochan = chaninfo[k];
  2180. buf[n + thisochan] = (float)(buf[n + thisochan] * thisgain);
  2181. }
  2182. thisgain += gainincr;
  2183. if(gainincr > 0.0) // Avoid rounding errors
  2184. thisgain = min(thisgain,nextgain);
  2185. else if(gainincr < 0.0)
  2186. thisgain = max(thisgain,nextgain);
  2187. }
  2188. if((exit_status = write_samps(buf,dz->ssampsread,dz))<0)
  2189. return(exit_status);
  2190. if((exit_status = read_samps(buf,dz))<0)
  2191. return(exit_status);
  2192. }
  2193. return FINISHED;
  2194. }