fracture.c 167 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560
  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. #ifdef unix
  41. #include <aaio.h>
  42. #endif
  43. #if defined unix || defined __GNUC__
  44. #define round(x) lround((x))
  45. #endif
  46. #ifndef HUGE
  47. #define HUGE 3.40282347e+38F
  48. #endif
  49. // Use existing "long" items in struct "dz" to remember various process constants
  50. #define envcount itemcnt // Number of timed-envelope entries
  51. #define envsrcs ringsize // number of the array at which envelope data begins
  52. #define envbuf rampbrksize // number of the array where interpolated envelope is constructed
  53. #define outlevs temp_sampsize // number of the array where current levels on each multichan out-channel are stored
  54. #define fltcnt is_transpos // Constant related to the order of the filter
  55. #define fltmul is_flat // Filter multiplier
  56. #define fltractv could_be_pitch // Flags whether filtering will be required
  57. #define fulldur is_sharp // Duration of event
  58. #define SIGNAL_TO_LEFT (0) // Parameters for stereo-hole-in-middle-compensation
  59. #define SIGNAL_TO_RIGHT (1)
  60. #define ROOT2 (1.4142136)
  61. #define FILTER_GAIN (-96.0) // Filter gain for lo-pass filter
  62. #define FLT_LPHP_ARRAYS_PER_FILTER (4)
  63. #define FLT_DEN1 (0)
  64. #define FLT_DEN2 (1)
  65. #define FLT_CN (2)
  66. #define FLT_S1_BASE (3)
  67. #define FLT_S2_BASE (4)
  68. #define FLT_E1_BASE (5)
  69. #define FLT_E2_BASE (6)
  70. char errstr[2400];
  71. int anal_infiles = 1;
  72. int sloom = 0;
  73. int sloombatch = 0;
  74. const char* cdp_version = "7.1.0";
  75. //CDP LIB REPLACEMENTS
  76. static int check_fracture_param_validity_and_consistency(dataptr dz);
  77. static int setup_fracture_application(dataptr dz);
  78. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  79. static int parse_infile_and_check_type(char **cmdline,dataptr dz);
  80. static int setup_fracture_param_ranges_and_defaults(dataptr dz);
  81. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz);
  82. static int open_the_outfile(dataptr dz);
  83. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  84. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  85. static int establish_application(dataptr dz);
  86. static int initialise_vflags(dataptr dz);
  87. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  88. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  89. static int mark_parameter_types(dataptr dz,aplptr ap);
  90. static int assign_file_data_storage(int infilecnt,dataptr dz);
  91. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  92. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  93. static int get_the_mode_from_cmdline(char *str,dataptr dz);
  94. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  95. static int fracture(int ibuflen,int envbuflen,int overflow,dataptr dz);
  96. static int handle_the_special_data(char *,dataptr dz);
  97. static int read_the_special_data(dataptr dz);
  98. static int fragment_param_preprocess (int *maxpulse,double *maxtrans,int *minfragmax,dataptr dz);
  99. static int create_fracture_sndbufs(int maxpulse,double maxtrans,int minfragmax,int *ibuflen,int *envbuflen,int *overflow,int *mbuflen,dataptr dz);
  100. static int read_the_envelope(double now, dataptr dz);
  101. static int getstakwritestt(double stakcntr,int ldur,double incr);
  102. static double getstakcentre(double *tempenv,dataptr dz);
  103. static void pancalc(double position,double *leftgain,double *rightgain);
  104. // mode > 0
  105. static int panspread(int *sectcnt,double *centre,double *spread,int *cntrswitch,int *outside,double *fmix,int samps_to_process,dataptr dz);
  106. static int spread_pan(double *thiscentre,int *cntrswitch,int *outside,double *spread,double *fmix,dataptr dz);
  107. static int filter_process(int *samps_to_process,int *endzeros,dataptr dz);
  108. static int do_lphp_filter_stereo(dataptr dz);
  109. static int lphp_filt_stereo(double *e1,double *e2,double *s1,double *s2,double *den1,double *den2,double *cn,dataptr dz,int chan);
  110. static int setup_lphp_filter(dataptr dz);
  111. static int establish_order_of_filter(double passfrq,double stopfrq,dataptr dz);
  112. static int allocate_internal_params_lphp(dataptr dz);
  113. static void calculate_filter_poles_lphp(double signd,int filter_order,double passfrq,dataptr dz);
  114. static void initialise_filter_coeffs_lphp(dataptr dz);
  115. /**************************************** MAIN *********************************************/
  116. int main(int argc,char *argv[])
  117. {
  118. int exit_status;
  119. dataptr dz = NULL;
  120. char **cmdline;
  121. int cmdlinecnt;
  122. int maxpulse = 0, ibuflen = 0, envbuflen = 0, minfragmax = 0, overflow = 0, mbuflen = 0;
  123. double maxtrans = 1.0;
  124. // aplptr ap;
  125. int is_launched = FALSE;
  126. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  127. fprintf(stdout,"%s\n",cdp_version);
  128. fflush(stdout);
  129. return 0;
  130. }
  131. /* CHECK FOR SOUNDLOOM */
  132. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  133. sloom = 0;
  134. sloombatch = 1;
  135. }
  136. if(sflinit("cdp")){
  137. sfperror("cdp: initialisation\n");
  138. return(FAILED);
  139. }
  140. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  141. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  142. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  143. return(FAILED);
  144. }
  145. if(!sloom) {
  146. if(argc == 1) {
  147. usage1();
  148. return(FAILED);
  149. } else if(argc == 2) {
  150. usage2(argv[1]);
  151. return(FAILED);
  152. }
  153. }
  154. if(!sloom) {
  155. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  156. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  157. return(FAILED);
  158. }
  159. cmdline = argv;
  160. cmdlinecnt = argc;
  161. if((get_the_process_no(argv[0],dz))<0)
  162. return(FAILED);
  163. cmdline++;
  164. cmdlinecnt--;
  165. dz->maxmode = 2;
  166. if((exit_status = get_the_mode_from_cmdline(cmdline[0],dz))<0) {
  167. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  168. return(exit_status);
  169. }
  170. cmdline++;
  171. cmdlinecnt--;
  172. // setup_particular_application =
  173. if((exit_status = setup_fracture_application(dz))<0) {
  174. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  175. return(FAILED);
  176. }
  177. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  178. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  179. return(FAILED);
  180. }
  181. } else {
  182. //parse_TK_data() =
  183. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  184. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  185. return(exit_status);
  186. }
  187. }
  188. // ap = dz->application;
  189. // parse_infile_and_hone_type() =
  190. if((exit_status = parse_infile_and_check_type(cmdline,dz))<0) {
  191. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  192. return(FAILED);
  193. }
  194. // setup_param_ranges_and_defaults() =
  195. if((exit_status = setup_fracture_param_ranges_and_defaults(dz))<0) {
  196. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  197. return(FAILED);
  198. }
  199. // open_first_infile CDP LIB
  200. if((exit_status = open_first_infile(cmdline[0],dz))<0) {
  201. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  202. return(FAILED);
  203. }
  204. cmdlinecnt--;
  205. cmdline++;
  206. // handle_extra_infiles() : redundant
  207. // handle_outfile() =
  208. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,dz))<0) {
  209. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  210. return(FAILED);
  211. }
  212. // handle_formants() redundant
  213. // handle_formant_quiksearch() redundant
  214. if((exit_status = handle_the_special_data(cmdline[0],dz))<0) {
  215. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  216. return(FAILED);
  217. }
  218. cmdlinecnt--;
  219. cmdline++;
  220. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  221. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  222. return(FAILED);
  223. }
  224. // check_param_validity_and_consistency....
  225. if((exit_status = check_fracture_param_validity_and_consistency(dz))<0) {
  226. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  227. return(FAILED);
  228. }
  229. if((exit_status = fragment_param_preprocess(&maxpulse,&maxtrans,&minfragmax,dz))<0) {
  230. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  231. return(FAILED);
  232. }
  233. is_launched = TRUE;
  234. if((exit_status = create_fracture_sndbufs(maxpulse,maxtrans,minfragmax,&ibuflen,&envbuflen,&overflow,&mbuflen,dz))<0) {
  235. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  236. return(FAILED);
  237. }
  238. if((exit_status = open_the_outfile(dz))<0) {
  239. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  240. return(FAILED);
  241. }
  242. if((exit_status = fracture(ibuflen,envbuflen,overflow,dz))<0) {
  243. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  244. return(FAILED);
  245. }
  246. if((exit_status = complete_output(dz))<0) { // CDP LIB
  247. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  248. return(FAILED);
  249. }
  250. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  251. free(dz);
  252. return(SUCCEEDED);
  253. }
  254. /**********************************************
  255. REPLACED CDP LIB FUNCTIONS
  256. **********************************************/
  257. /****************************** SET_PARAM_DATA *********************************/
  258. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  259. {
  260. ap->special_data = (char)special_data;
  261. ap->param_cnt = (char)paramcnt;
  262. ap->max_param_cnt = (char)maxparamcnt;
  263. if(ap->max_param_cnt>0) {
  264. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  265. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  266. return(MEMORY_ERROR);
  267. }
  268. strcpy(ap->param_list,paramlist);
  269. }
  270. return(FINISHED);
  271. }
  272. /****************************** SET_VFLGS *********************************/
  273. int set_vflgs
  274. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  275. {
  276. ap->option_cnt = (char) optcnt; /*RWD added cast */
  277. if(optcnt) {
  278. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  279. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  280. return(MEMORY_ERROR);
  281. }
  282. strcpy(ap->option_list,optlist);
  283. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  284. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  285. return(MEMORY_ERROR);
  286. }
  287. strcpy(ap->option_flags,optflags);
  288. }
  289. ap->vflag_cnt = (char) vflagcnt;
  290. ap->variant_param_cnt = (char) vparamcnt;
  291. if(vflagcnt) {
  292. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  293. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  294. return(MEMORY_ERROR);
  295. }
  296. strcpy(ap->variant_list,varlist);
  297. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  298. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  299. return(MEMORY_ERROR);
  300. }
  301. strcpy(ap->variant_flags,varflags);
  302. }
  303. return(FINISHED);
  304. }
  305. /***************************** APPLICATION_INIT **************************/
  306. int application_init(dataptr dz)
  307. {
  308. int exit_status;
  309. int storage_cnt;
  310. int tipc, brkcnt;
  311. aplptr ap = dz->application;
  312. if(ap->vflag_cnt>0)
  313. initialise_vflags(dz);
  314. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  315. ap->total_input_param_cnt = (char)tipc;
  316. if(tipc>0) {
  317. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  318. return(exit_status);
  319. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  320. return(exit_status);
  321. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  322. return(exit_status);
  323. }
  324. brkcnt = tipc;
  325. //THERE ARE NO INPUTFILE brktables USED IN THIS PROCESS
  326. if(brkcnt>0) {
  327. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  328. return(exit_status);
  329. }
  330. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  331. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  332. return(exit_status);
  333. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  334. return(exit_status);
  335. }
  336. if((exit_status = mark_parameter_types(dz,ap))<0)
  337. return(exit_status);
  338. // establish_infile_constants() replaced by
  339. dz->infilecnt = 1;
  340. //establish_bufptrs_and_extra_buffers():
  341. return(FINISHED);
  342. }
  343. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  344. /* RWD malloc changed to calloc; helps debug version run as release! */
  345. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  346. {
  347. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  348. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  349. return(MEMORY_ERROR);
  350. }
  351. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  352. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  353. return(MEMORY_ERROR);
  354. }
  355. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  356. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  357. return(MEMORY_ERROR);
  358. }
  359. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  360. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  361. return(MEMORY_ERROR);
  362. }
  363. return(FINISHED);
  364. }
  365. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  366. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  367. {
  368. int n;
  369. for(n=0;n<storage_cnt;n++) {
  370. dz->is_int[n] = (char)0;
  371. dz->no_brk[n] = (char)0;
  372. }
  373. return(FINISHED);
  374. }
  375. /***************************** MARK_PARAMETER_TYPES **************************/
  376. int mark_parameter_types(dataptr dz,aplptr ap)
  377. {
  378. int n, m; /* PARAMS */
  379. for(n=0;n<ap->max_param_cnt;n++) {
  380. switch(ap->param_list[n]) {
  381. case('0'): break; /* dz->is_active[n] = 0 is default */
  382. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  383. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  384. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  385. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  386. default:
  387. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  388. return(PROGRAM_ERROR);
  389. }
  390. } /* OPTIONS */
  391. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  392. switch(ap->option_list[n]) {
  393. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  394. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  395. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  396. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  397. default:
  398. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  399. return(PROGRAM_ERROR);
  400. }
  401. } /* VARIANTS */
  402. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  403. switch(ap->variant_list[n]) {
  404. case('0'): break;
  405. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  406. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  407. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  408. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  409. default:
  410. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  411. return(PROGRAM_ERROR);
  412. }
  413. } /* INTERNAL */
  414. for(n=0,
  415. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  416. switch(ap->internal_param_list[n]) {
  417. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  418. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  419. case('d'): dz->no_brk[m] = (char)1; break;
  420. default:
  421. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  422. return(PROGRAM_ERROR);
  423. }
  424. }
  425. return(FINISHED);
  426. }
  427. /************************ HANDLE_THE_OUTFILE *********************/
  428. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz)
  429. {
  430. char *filename = (*cmdline)[0], *p;
  431. if(filename[0]=='-' && filename[1]=='f') {
  432. dz->floatsam_output = 1;
  433. dz->true_outfile_stype = SAMP_FLOAT;
  434. filename+= 2;
  435. }
  436. if(!sloom) {
  437. if(file_has_invalid_startchar(filename) || value_is_numeric(filename)) {
  438. sprintf(errstr,"Outfile name %s has invalid start character(s) or looks too much like a number.\n",filename);
  439. return(DATA_ERROR);
  440. }
  441. }
  442. p = filename; // Drop file extension
  443. while(*p != ENDOFSTR) {
  444. if(*p == '.') {
  445. *p = ENDOFSTR;
  446. break;
  447. }
  448. p++;
  449. }
  450. strcpy(dz->outfilename,filename);
  451. (*cmdline)++;
  452. (*cmdlinecnt)--;
  453. return(FINISHED);
  454. }
  455. /************************ OPEN_THE_OUTFILE *********************/
  456. int open_the_outfile(dataptr dz)
  457. {
  458. int exit_status;
  459. dz->infile->channels = dz->iparam[FRAC_CHANS];
  460. if((exit_status = create_sized_outfile(dz->outfilename,dz))<0)
  461. return(exit_status);
  462. dz->infile->channels = 1;
  463. return(FINISHED);
  464. }
  465. /***************************** ESTABLISH_APPLICATION **************************/
  466. int establish_application(dataptr dz)
  467. {
  468. aplptr ap;
  469. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  470. sprintf(errstr,"establish_application()\n");
  471. return(MEMORY_ERROR);
  472. }
  473. ap = dz->application;
  474. memset((char *)ap,0,sizeof(struct applic));
  475. return(FINISHED);
  476. }
  477. /************************* INITIALISE_VFLAGS *************************/
  478. int initialise_vflags(dataptr dz)
  479. {
  480. int n;
  481. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  482. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  483. return(MEMORY_ERROR);
  484. }
  485. for(n=0;n<dz->application->vflag_cnt;n++)
  486. dz->vflag[n] = FALSE;
  487. return FINISHED;
  488. }
  489. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  490. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  491. {
  492. int n;
  493. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  494. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  495. return(MEMORY_ERROR);
  496. }
  497. for(n=0;n<tipc;n++)
  498. ap->default_val[n] = 0.0;
  499. return(FINISHED);
  500. }
  501. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  502. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  503. {
  504. int n;
  505. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  506. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  507. return(MEMORY_ERROR);
  508. }
  509. for(n=0;n<tipc;n++)
  510. dz->is_active[n] = (char)0;
  511. return(FINISHED);
  512. }
  513. /************************* SETUP_FRACTURE_APPLICATION *******************/
  514. int setup_fracture_application(dataptr dz)
  515. {
  516. int exit_status;
  517. aplptr ap;
  518. if((exit_status = establish_application(dz))<0) // GLOBAL
  519. return(FAILED);
  520. ap = dz->application;
  521. // SEE parstruct FOR EXPLANATION of next 2 functions
  522. if(dz->mode == 0) {
  523. if((exit_status = set_param_data(ap,ENVSERIES,9,5,"iiDDD0000"))<0)
  524. return(FAILED);
  525. if((exit_status = set_vflgs(ap,"rpdvestSmM",10,"DDDDDDDiDD","yl",2,0,"00"))<0)
  526. return(FAILED);
  527. } else {
  528. if((exit_status = set_param_data(ap,ENVSERIES,9,9,"iiDDDiDdd"))<0)
  529. return(FAILED);
  530. if((exit_status = set_vflgs(ap,"rpdvesthmiazclfjkwg",19,"DDDDDDDiDDddddddddd","y",1,0,"0"))<0)
  531. return(FAILED);
  532. }
  533. // set_legal_infile_structure -->
  534. dz->has_otherfile = FALSE;
  535. // assign_process_logic -->
  536. dz->input_data_type = SNDFILES_ONLY;
  537. dz->process_type = UNEQUAL_SNDFILE;
  538. dz->outfiletype = SNDFILE_OUT;
  539. return application_init(dz); //GLOBAL
  540. }
  541. /************************* PARSE_INFILE_AND_CHECK_TYPE *******************/
  542. int parse_infile_and_check_type(char **cmdline,dataptr dz)
  543. {
  544. int exit_status;
  545. infileptr infile_info;
  546. if(!sloom) {
  547. if((infile_info = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  548. sprintf(errstr,"INSUFFICIENT MEMORY for infile structure to test file data.");
  549. return(MEMORY_ERROR);
  550. } else if((exit_status = cdparse(cmdline[0],infile_info))<0) {
  551. sprintf(errstr,"Failed to parse input file %s\n",cmdline[0]);
  552. return(PROGRAM_ERROR);
  553. } else if(infile_info->filetype != SNDFILE) {
  554. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  555. return(DATA_ERROR);
  556. } else if(infile_info->channels != 1) {
  557. sprintf(errstr,"File %s is not of correct type (must be mono)\n",cmdline[0]);
  558. return(DATA_ERROR);
  559. } else if((exit_status = copy_parse_info_to_main_structure(infile_info,dz))<0) {
  560. sprintf(errstr,"Failed to copy file parsing information\n");
  561. return(PROGRAM_ERROR);
  562. }
  563. free(infile_info);
  564. }
  565. return(FINISHED);
  566. }
  567. /************************* SETUP_FRACTURE_PARAM_RANGES_AND_DEFAULTS *******************/
  568. int setup_fracture_param_ranges_and_defaults(dataptr dz)
  569. {
  570. int exit_status;
  571. aplptr ap = dz->application;
  572. // set_param_ranges()
  573. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  574. // NB total_input_param_cnt is > 0 !!!
  575. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  576. return(FAILED);
  577. // get_param_ranges()
  578. ap->hi[FRAC_CHANS] = 16;
  579. if(dz->mode == 0) {
  580. ap->lo[FRAC_CHANS] = 2;
  581. ap->default_val[FRAC_CHANS] = 2;
  582. } else {
  583. ap->lo[FRAC_CHANS] = 4;
  584. ap->default_val[FRAC_CHANS] = 8;
  585. }
  586. ap->lo[FRAC_STRMS] = 4;
  587. ap->hi[FRAC_STRMS] = 512;
  588. ap->default_val[FRAC_STRMS] = 16;
  589. ap->lo[FRAC_PULSE] = .05;
  590. ap->hi[FRAC_PULSE] = 8;
  591. ap->default_val[FRAC_PULSE] = 1;
  592. ap->lo[FRAC_DEPTH] = 0;
  593. ap->hi[FRAC_DEPTH] = 8;
  594. ap->default_val[FRAC_DEPTH] = 1;
  595. ap->lo[FRAC_STACK] = 0;
  596. ap->hi[FRAC_STACK] = 12;
  597. ap->default_val[FRAC_STACK] = 0;
  598. ap->lo[FRAC_INRND] = 0;
  599. ap->hi[FRAC_INRND] = 1;
  600. ap->default_val[FRAC_INRND] = 0;
  601. ap->lo[FRAC_OUTRND] = 0;
  602. ap->hi[FRAC_OUTRND] = 1;
  603. ap->default_val[FRAC_OUTRND] = 0;
  604. ap->lo[FRAC_SCAT] = 0;
  605. ap->hi[FRAC_SCAT] = 1;
  606. ap->default_val[FRAC_SCAT] = 0;
  607. ap->lo[FRAC_LEVRND] = 0;
  608. ap->hi[FRAC_LEVRND] = 1;
  609. ap->default_val[FRAC_LEVRND] = 0;
  610. ap->lo[FRAC_ENVRND] = 0;
  611. ap->hi[FRAC_ENVRND] = 32767;
  612. ap->default_val[FRAC_ENVRND] = 0;
  613. ap->lo[FRAC_STKRND] = 0;
  614. ap->hi[FRAC_STKRND] = 1;
  615. ap->default_val[FRAC_STKRND] = 0;
  616. ap->lo[FRAC_PCHRND] = 0;
  617. ap->hi[FRAC_PCHRND] = 1200;
  618. ap->default_val[FRAC_PCHRND] = 0;
  619. ap->lo[FRAC_SEED] = 0;
  620. ap->hi[FRAC_SEED] = 32767;
  621. ap->default_val[FRAC_SEED] = 0;
  622. ap->lo[FRAC_MIN] = 0;
  623. ap->hi[FRAC_MIN] = 1;
  624. ap->default_val[FRAC_MIN] = 0;
  625. ap->lo[FRAC_MAX] = 0;
  626. ap->hi[FRAC_MAX] = 16;
  627. ap->default_val[FRAC_MAX] = 0;
  628. if(dz->mode > 0) {
  629. ap->lo[FRAC_CENTRE] = 0;
  630. ap->hi[FRAC_CENTRE] = 16;
  631. ap->default_val[FRAC_CENTRE] = 1;
  632. ap->lo[FRAC_FRONT] = -4; // -2= -infinity : further -2 allows for max-mdepth (* 2) as rear of moving-front dragged behind front
  633. ap->hi[FRAC_FRONT] = 2; // 2 = +infinity
  634. ap->default_val[FRAC_FRONT] = 0;
  635. ap->lo[FRAC_MDEPTH] = 0;
  636. ap->hi[FRAC_MDEPTH] = 1;
  637. ap->default_val[FRAC_MDEPTH] = 0.5;
  638. ap->lo[FRAC_ROLLOFF] = 0.0;
  639. ap->hi[FRAC_ROLLOFF] = 1.0;
  640. ap->default_val[FRAC_ROLLOFF] = 0.0;
  641. ap->lo[FRAC_ATTEN] = 1.0;
  642. ap->hi[FRAC_ATTEN] = 10.0;
  643. ap->default_val[FRAC_ATTEN] = 3.0;
  644. ap->lo[FRAC_ZPOINT] = 0.0;
  645. ap->hi[FRAC_ZPOINT] = 1.0;
  646. ap->default_val[FRAC_ZPOINT] = 0.66;
  647. ap->lo[FRAC_CONTRACT] = 0.0;
  648. ap->hi[FRAC_CONTRACT] = 1.0;
  649. ap->default_val[FRAC_CONTRACT] = 0.66;
  650. ap->lo[FRAC_FPOINT] = 0.0;
  651. ap->hi[FRAC_FPOINT] = 1.0;
  652. ap->default_val[FRAC_FPOINT] = 0.66;
  653. ap->lo[FRAC_FFACTOR] = 0.0;
  654. ap->hi[FRAC_FFACTOR] = 1.0;
  655. ap->default_val[FRAC_FFACTOR] = 0.66;
  656. ap->lo[FRAC_FFREQ] = 10.0;
  657. ap->hi[FRAC_FFREQ] = (dz->nyquist/2.0) * 0.8;
  658. ap->default_val[FRAC_FFREQ] = 500.0;
  659. ap->lo[FRAC_UP] = 0.0;
  660. ap->hi[FRAC_UP] = 1.0;
  661. ap->default_val[FRAC_UP] = 0.0;
  662. ap->lo[FRAC_DN] = 0.0;
  663. ap->hi[FRAC_DN] = 1.0;
  664. ap->default_val[FRAC_DN] = 0.0;
  665. ap->lo[FRAC_GAIN] = 0.0;
  666. ap->hi[FRAC_GAIN] = 1.0;
  667. ap->default_val[FRAC_GAIN] = 1.0;
  668. }
  669. dz->maxmode = 2;
  670. if(!sloom)
  671. put_default_vals_in_all_params(dz);
  672. return(FINISHED);
  673. }
  674. /********************************* PARSE_SLOOM_DATA *********************************/
  675. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  676. {
  677. int exit_status;
  678. int cnt = 1, infilecnt;
  679. int filesize, insams, inbrksize;
  680. double dummy;
  681. int true_cnt = 0;
  682. // aplptr ap;
  683. while(cnt<=PRE_CMDLINE_DATACNT) {
  684. if(cnt > argc) {
  685. sprintf(errstr,"Insufficient data sent from TK\n");
  686. return(DATA_ERROR);
  687. }
  688. switch(cnt) {
  689. case(1):
  690. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  691. sprintf(errstr,"Cannot read process no. sent from TK\n");
  692. return(DATA_ERROR);
  693. }
  694. break;
  695. case(2):
  696. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  697. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  698. return(DATA_ERROR);
  699. }
  700. if(dz->mode > 0)
  701. dz->mode--;
  702. //setup_particular_application() =
  703. if((exit_status = setup_fracture_application(dz))<0)
  704. return(exit_status);
  705. // ap = dz->application;
  706. break;
  707. case(3):
  708. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  709. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  710. return(DATA_ERROR);
  711. }
  712. if(infilecnt < 1) {
  713. true_cnt = cnt + 1;
  714. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  715. }
  716. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  717. return(exit_status);
  718. break;
  719. case(INPUT_FILETYPE+4):
  720. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  721. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  722. return(DATA_ERROR);
  723. }
  724. break;
  725. case(INPUT_FILESIZE+4):
  726. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  727. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  728. return(DATA_ERROR);
  729. }
  730. dz->insams[0] = filesize;
  731. break;
  732. case(INPUT_INSAMS+4):
  733. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  734. sprintf(errstr,"Cannot read insams sent from TK\n");
  735. return(DATA_ERROR);
  736. }
  737. dz->insams[0] = insams;
  738. break;
  739. case(INPUT_SRATE+4):
  740. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  741. sprintf(errstr,"Cannot read srate sent from TK\n");
  742. return(DATA_ERROR);
  743. }
  744. break;
  745. case(INPUT_CHANNELS+4):
  746. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  747. sprintf(errstr,"Cannot read channels sent from TK\n");
  748. return(DATA_ERROR);
  749. }
  750. break;
  751. case(INPUT_STYPE+4):
  752. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  753. sprintf(errstr,"Cannot read stype sent from TK\n");
  754. return(DATA_ERROR);
  755. }
  756. break;
  757. case(INPUT_ORIGSTYPE+4):
  758. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  759. sprintf(errstr,"Cannot read origstype sent from TK\n");
  760. return(DATA_ERROR);
  761. }
  762. break;
  763. case(INPUT_ORIGRATE+4):
  764. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  765. sprintf(errstr,"Cannot read origrate sent from TK\n");
  766. return(DATA_ERROR);
  767. }
  768. break;
  769. case(INPUT_MLEN+4):
  770. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  771. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  772. return(DATA_ERROR);
  773. }
  774. break;
  775. case(INPUT_DFAC+4):
  776. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  777. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  778. return(DATA_ERROR);
  779. }
  780. break;
  781. case(INPUT_ORIGCHANS+4):
  782. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  783. sprintf(errstr,"Cannot read origchans sent from TK\n");
  784. return(DATA_ERROR);
  785. }
  786. break;
  787. case(INPUT_SPECENVCNT+4):
  788. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  789. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  790. return(DATA_ERROR);
  791. }
  792. dz->specenvcnt = dz->infile->specenvcnt;
  793. break;
  794. case(INPUT_WANTED+4):
  795. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  796. sprintf(errstr,"Cannot read wanted sent from TK\n");
  797. return(DATA_ERROR);
  798. }
  799. break;
  800. case(INPUT_WLENGTH+4):
  801. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  802. sprintf(errstr,"Cannot read wlength sent from TK\n");
  803. return(DATA_ERROR);
  804. }
  805. break;
  806. case(INPUT_OUT_CHANS+4):
  807. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  808. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  809. return(DATA_ERROR);
  810. }
  811. break;
  812. /* RWD these chanegs to samps - tk will have to deal with that! */
  813. case(INPUT_DESCRIPTOR_BYTES+4):
  814. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  815. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  816. return(DATA_ERROR);
  817. }
  818. break;
  819. case(INPUT_IS_TRANSPOS+4):
  820. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  821. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  822. return(DATA_ERROR);
  823. }
  824. break;
  825. case(INPUT_COULD_BE_TRANSPOS+4):
  826. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  827. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  828. return(DATA_ERROR);
  829. }
  830. break;
  831. case(INPUT_COULD_BE_PITCH+4):
  832. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  833. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  834. return(DATA_ERROR);
  835. }
  836. break;
  837. case(INPUT_DIFFERENT_SRATES+4):
  838. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  839. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  840. return(DATA_ERROR);
  841. }
  842. break;
  843. case(INPUT_DUPLICATE_SNDS+4):
  844. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  845. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  846. return(DATA_ERROR);
  847. }
  848. break;
  849. case(INPUT_BRKSIZE+4):
  850. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  851. sprintf(errstr,"Cannot read brksize sent from TK\n");
  852. return(DATA_ERROR);
  853. }
  854. if(inbrksize > 0) {
  855. switch(dz->input_data_type) {
  856. case(WORDLIST_ONLY):
  857. break;
  858. case(PITCH_AND_PITCH):
  859. case(PITCH_AND_TRANSPOS):
  860. case(TRANSPOS_AND_TRANSPOS):
  861. dz->tempsize = inbrksize;
  862. break;
  863. case(BRKFILES_ONLY):
  864. case(UNRANGED_BRKFILE_ONLY):
  865. case(DB_BRKFILES_ONLY):
  866. case(ALL_FILES):
  867. case(ANY_NUMBER_OF_ANY_FILES):
  868. if(dz->extrabrkno < 0) {
  869. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  870. return(DATA_ERROR);
  871. }
  872. if(dz->brksize == NULL) {
  873. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  874. return(PROGRAM_ERROR);
  875. }
  876. dz->brksize[dz->extrabrkno] = inbrksize;
  877. break;
  878. default:
  879. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  880. dz->input_data_type);
  881. return(PROGRAM_ERROR);
  882. }
  883. break;
  884. }
  885. break;
  886. case(INPUT_NUMSIZE+4):
  887. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  888. sprintf(errstr,"Cannot read numsize sent from TK\n");
  889. return(DATA_ERROR);
  890. }
  891. break;
  892. case(INPUT_LINECNT+4):
  893. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  894. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  895. return(DATA_ERROR);
  896. }
  897. break;
  898. case(INPUT_ALL_WORDS+4):
  899. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  900. sprintf(errstr,"Cannot read all_words sent from TK\n");
  901. return(DATA_ERROR);
  902. }
  903. break;
  904. case(INPUT_ARATE+4):
  905. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  906. sprintf(errstr,"Cannot read arate sent from TK\n");
  907. return(DATA_ERROR);
  908. }
  909. break;
  910. case(INPUT_FRAMETIME+4):
  911. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  912. sprintf(errstr,"Cannot read frametime sent from TK\n");
  913. return(DATA_ERROR);
  914. }
  915. dz->frametime = (float)dummy;
  916. break;
  917. case(INPUT_WINDOW_SIZE+4):
  918. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  919. sprintf(errstr,"Cannot read window_size sent from TK\n");
  920. return(DATA_ERROR);
  921. }
  922. break;
  923. case(INPUT_NYQUIST+4):
  924. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  925. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  926. return(DATA_ERROR);
  927. }
  928. break;
  929. case(INPUT_DURATION+4):
  930. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  931. sprintf(errstr,"Cannot read duration sent from TK\n");
  932. return(DATA_ERROR);
  933. }
  934. break;
  935. case(INPUT_MINBRK+4):
  936. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  937. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  938. return(DATA_ERROR);
  939. }
  940. break;
  941. case(INPUT_MAXBRK+4):
  942. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  943. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  944. return(DATA_ERROR);
  945. }
  946. break;
  947. case(INPUT_MINNUM+4):
  948. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  949. sprintf(errstr,"Cannot read minnum sent from TK\n");
  950. return(DATA_ERROR);
  951. }
  952. break;
  953. case(INPUT_MAXNUM+4):
  954. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  955. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  956. return(DATA_ERROR);
  957. }
  958. break;
  959. default:
  960. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  961. return(PROGRAM_ERROR);
  962. }
  963. cnt++;
  964. }
  965. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  966. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  967. return(DATA_ERROR);
  968. }
  969. if(true_cnt)
  970. cnt = true_cnt;
  971. *cmdlinecnt = 0;
  972. while(cnt < argc) {
  973. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  974. return(exit_status);
  975. cnt++;
  976. }
  977. return(FINISHED);
  978. }
  979. /********************************* GET_TK_CMDLINE_WORD *********************************/
  980. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  981. {
  982. if(*cmdlinecnt==0) {
  983. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  984. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  985. return(MEMORY_ERROR);
  986. }
  987. } else {
  988. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  989. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  990. return(MEMORY_ERROR);
  991. }
  992. }
  993. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  994. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  995. return(MEMORY_ERROR);
  996. }
  997. strcpy((*cmdline)[*cmdlinecnt],q);
  998. (*cmdlinecnt)++;
  999. return(FINISHED);
  1000. }
  1001. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  1002. int assign_file_data_storage(int infilecnt,dataptr dz)
  1003. {
  1004. int exit_status;
  1005. int no_sndfile_system_files = FALSE;
  1006. dz->infilecnt = infilecnt;
  1007. if((exit_status = allocate_filespace(dz))<0)
  1008. return(exit_status);
  1009. if(no_sndfile_system_files)
  1010. dz->infilecnt = 0;
  1011. return(FINISHED);
  1012. }
  1013. /************************* redundant functions: to ensure libs compile OK *******************/
  1014. int assign_process_logic(dataptr dz)
  1015. {
  1016. return(FINISHED);
  1017. }
  1018. void set_legal_infile_structure(dataptr dz)
  1019. {}
  1020. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  1021. {
  1022. return(FINISHED);
  1023. }
  1024. int setup_internal_arrays_and_array_pointers(dataptr dz)
  1025. {
  1026. return(FINISHED);
  1027. }
  1028. int establish_bufptrs_and_extra_buffers(dataptr dz)
  1029. {
  1030. return(FINISHED);
  1031. }
  1032. int read_special_data(char *str,dataptr dz)
  1033. {
  1034. return(FINISHED);
  1035. }
  1036. int inner_loop
  1037. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  1038. {
  1039. return(FINISHED);
  1040. }
  1041. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1042. {
  1043. return(FINISHED);
  1044. }
  1045. /******************************** USAGE1 ********************************/
  1046. int usage1(void)
  1047. {
  1048. usage2("fracture");
  1049. return(USAGE_ONLY);
  1050. }
  1051. /**************************** CHECK_FRACTURE_PARAM_VALIDITY_AND_CONSISTENCY *****************************/
  1052. int check_fracture_param_validity_and_consistency(dataptr dz)
  1053. {
  1054. int exit_status;
  1055. double maxval, minval, xs;
  1056. int n,m;
  1057. if(dz->brksize[FRAC_STACK]) {
  1058. for(n=0,m=1;n < dz->brksize[FRAC_STACK];n++,m+=2) {
  1059. if(dz->brk[FRAC_STACK][m] <= 0.0) {
  1060. sprintf(errstr,"Stacking value cannot be zero inside a breakpoint file,\n");
  1061. return(DATA_ERROR);
  1062. }
  1063. }
  1064. }
  1065. if(dz->iparam[FRAC_SEED] > 0)
  1066. srand((int)dz->iparam[FRAC_SEED]);
  1067. if(dz->brksize[FRAC_DEPTH]) {
  1068. if((exit_status = get_maxvalue_in_brktable(&maxval,FRAC_DEPTH,dz))<0)
  1069. return PROGRAM_ERROR;
  1070. } else
  1071. maxval = dz->param[FRAC_DEPTH];
  1072. if(maxval <= 1.0) {
  1073. if(dz->brksize[FRAC_STACK] || (dz->param[FRAC_STACK] != 0)) {
  1074. fprintf(stdout,"WARNING: Stack parameter set, but Depth never exceeds 1, so no stacking.\n");
  1075. fflush(stdout);
  1076. dz->brksize[FRAC_STACK] = 0;
  1077. dz->param[FRAC_STACK] = 0.0;
  1078. }
  1079. if(dz->brksize[FRAC_STKRND] || (dz->param[FRAC_STKRND] != 0)) {
  1080. fprintf(stdout,"WARNING: Stack randomisation parameter set, but Depth never exceeds 1, so no stacking.\n");
  1081. fflush(stdout);
  1082. dz->brksize[FRAC_STKRND] = 0;
  1083. dz->param[FRAC_STKRND] = 0.0;
  1084. }
  1085. } else { // If stack value will be operational, if set to zero, reset NOW to 12
  1086. if(!dz->brksize[FRAC_STACK] && dz->param[FRAC_STACK] == 0.0)
  1087. dz->param[FRAC_STACK] = 12.0;
  1088. }
  1089. if(dz->mode > 0) {
  1090. if(dz->iparam[FRAC_CHANS] % 4 != 0) {
  1091. sprintf(errstr,"Number of output channels must be a multiple of 4.\n");
  1092. return(DATA_ERROR);
  1093. }
  1094. xs = dz->param[FRAC_MDEPTH] * 2;
  1095. if(dz->brksize[FRAC_FRONT]) {
  1096. maxval = dz->brk[FRAC_FRONT][1];
  1097. minval = maxval;
  1098. for(n=1,m=3;n<dz->brksize[FRAC_FRONT];n++,m+=2) {
  1099. if(dz->brk[FRAC_FRONT][m] > minval) {
  1100. sprintf(errstr,"Front value must move from high values to low values,\n");
  1101. return(DATA_ERROR);
  1102. }
  1103. minval = dz->brk[FRAC_FRONT][m];
  1104. }
  1105. dz->fulldur = dz->brk[FRAC_FRONT][(dz->brksize[FRAC_FRONT] -1) * 2];
  1106. } else {
  1107. dz->fulldur = dz->duration;
  1108. maxval = dz->param[FRAC_FRONT];
  1109. minval = dz->param[FRAC_FRONT];
  1110. }
  1111. dz->fltractv = 0;
  1112. if(maxval > 1.0 || minval < -(1 + xs))
  1113. dz->fltractv = 1;
  1114. if(dz->param[FRAC_UP] + dz->param[FRAC_DN] >= 1.0) {
  1115. sprintf(errstr,"Fade up and Fade down times must add up to LESS THEN 1.\n");
  1116. return(DATA_ERROR);
  1117. }
  1118. dz->param[FRAC_UP] *= dz->fulldur;
  1119. dz->param[FRAC_DN] *= dz->fulldur;
  1120. }
  1121. return FINISHED;
  1122. }
  1123. /********************************************************************************************/
  1124. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1125. {
  1126. if(!strcmp(prog_identifier_from_cmdline,"fracture")) dz->process = FRACTURE;
  1127. else {
  1128. sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  1129. return(USAGE_ONLY);
  1130. }
  1131. return(FINISHED);
  1132. }
  1133. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  1134. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  1135. {
  1136. int n;
  1137. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1138. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  1139. return(MEMORY_ERROR);
  1140. }
  1141. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1142. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  1143. return(MEMORY_ERROR);
  1144. }
  1145. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1146. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  1147. return(MEMORY_ERROR);
  1148. }
  1149. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1150. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  1151. return(MEMORY_ERROR);
  1152. }
  1153. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1154. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  1155. return(MEMORY_ERROR);
  1156. }
  1157. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1158. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  1159. return(MEMORY_ERROR);
  1160. }
  1161. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1162. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  1163. return(MEMORY_ERROR);
  1164. }
  1165. for(n=0;n<brkcnt;n++) {
  1166. dz->brk[n] = NULL;
  1167. dz->brkptr[n] = NULL;
  1168. dz->brkinit[n] = 0;
  1169. dz->brksize[n] = 0;
  1170. }
  1171. return(FINISHED);
  1172. }
  1173. /******************************** USAGE2 ********************************/
  1174. int usage2(char *str)
  1175. {
  1176. if(!strcmp(str,"fracture")) {
  1177. fprintf(stderr,
  1178. "USAGE:fracture fracture 1\n"
  1179. "infil outfil etab chns strms pulse edpth stkint [-hseed] [-mmin] [-imax] [-rrrnd]\n"
  1180. "[-pprnd] [-ddisp] [-vlrnd] [-eernd] [-srnd] [-ttrnd] [-y] [-l]\n"
  1181. "\n"
  1182. "OR\n"
  1183. "\n"
  1184. "USAGE:fracture fracture 2\n"
  1185. "infil outfil etab chns strms pulse edpth stkint cntre frnt depth rolloff [-hseed]\n"
  1186. "[-mmin] [-imax] [-rrrnd] [-pprnd] [-ddisp] [-vlrnd] [-eernd] [-srnd] [-ttrnd]\n"
  1187. "[-aatten] [-zzpoint] [-ccontract] [] [-llopnt] [-ffmix] [-jffrq] [-kup] [-wdn] [-y]\n"
  1188. "\n"
  1189. "DISPERSE MONO SIGNAL INTO FRAGMENTS SPREAD OVER N-CHANNEL SPACE.\n"
  1190. "\n"
  1191. "Mode 1: Output is N-channel dispersal in N-channel space.\n"
  1192. "Mode 2: Output is stereo dispersal (posibly moving) in surround space.\n"
  1193. "\n"
  1194. "PRESS ANY KEY TO CONTINUE\n");
  1195. while(!kbhit())
  1196. ;
  1197. if(kbhit()) {
  1198. fprintf(stderr,
  1199. "ETAB Textfile: Each line is a TIME followed by 7 PAIRS of envelope-data.\n"
  1200. " envelope-data represented in form \"etime lev\"\n"
  1201. " where \"etime\" is relative time WITHIN envelope (values between 0 & 1)\n"
  1202. " and \"lev\" is level at etime (values 0-1). In each envelope-data set\n"
  1203. " \"lev\" must start and end at zero and rise to a max value of 1.0\n"
  1204. "CHNS Number of channels in output file (2-16). (Mode 2, multiples of 4 only).\n"
  1205. "STRMS No. of spatial positions (streams) for resulting fragments ( >=4 ).\n"
  1206. "PULSE Average gap btwn 1 set-of-frags (each in different strm) & next set.\n"
  1207. " Disp = 0: all frags in sync at each (possibly randomised) pulse.\n"
  1208. " Disp > 0: frags time-scattered around pulse centre. (see below).\n"
  1209. "EDPTH Envelope depth. 1: env cuts down to zero, 0.75: cuts 3/4 way to zero,\n"
  1210. "(+STACK) 0.1: cuts only 1/10 way to zero, 0: env has no effect on source.\n"
  1211. " Once depth exceeds 1, fragments begin to stack (but NOT before)\n"
  1212. " (i.e. transposed copies added to fragment, synced at envelope peak).\n"
  1213. " Depth 2 -> Stack 1: 1st transposed element added at full level.\n"
  1214. " Depth 1.5 -> Stack 06.5: 1st transpd element added at 1/2 (0.5) level.\n"
  1215. " Depth 2.5 -> Stack 1.5: 1st added at full level, 2nd at 1/2 level etc\n"
  1216. "STKINT Interval of (upward) transposition in stack, in semitones (0-12).\n"
  1217. " Default(0) is read as octave(12). NO ZEROS in stack brkpoint files.\n"
  1218. "SEED If NOT zero, repeating process with same seed gives identical output.\n"
  1219. "MIN/MAX Minimum/maximum duration of fragments. If zero, no minimum/maximum.\n"
  1220. "RRND Randomisation of read-time in src. Range 0-1.\n"
  1221. "PRND Randomisation of pulse-time in output. Range 0-1.\n"
  1222. " In both cases, Max(1) scatters in range +- half-duration of pulse.\n"
  1223. "DISP Dispersal (scatter) of output timings between different streams.\n"
  1224. " If pulse(+prnd) gives time \"P\", then for disp 0: all frags are at \"P\"\n"
  1225. " for disp 1: frags scattered within max range (+- half-dur of pulse).\n"
  1226. "LRND Randomisation of levels (volume) of fragments. Range 0 - 1.\n"
  1227. " 0: All frags full level. 1: Frags at random levels between 0 & full.\n"
  1228. "ERND Randomisation of envelope used. A time range (trange).\n"
  1229. " Event at \"now\" reads etable at randtime btwn \"now\" & now-minus-trange.\n"
  1230. "SRND Randomisation of stack. Range 0 - 1 (NB stack value (S) = DEPTH-1)\n"
  1231. " 0: Stack value is S. 1: Stack val selected at random between 0 & S.\n"
  1232. "TRND Random tranpose of fragments. Range 0-1200 cents (1 octave upwards).\n"
  1233. " Event pitch randomised between pitch+trnd and pitch-trnd.\n"
  1234. "-z Permit stacking of very short events. Default = forbid, prevent clipping.\n"
  1235. "-l For more than 2 output chans, lspkrs assumed to encircle listeners,\n"
  1236. " with a single lspkr at centre front.\n"
  1237. " Setting -l flag assumes linear array, with leftmost+rightmost lspkrs.\n"
  1238. "\n"
  1239. "NB: STKINT, MAX, RRND, LRND, SRND and TRND are INACTIVE if depth < 1.\n"
  1240. "All these params can timevary EXCEPT \"chns\", \"strms\" & \"seed\".\n"
  1241. "\n"
  1242. "PRESS KEY \"2\" TO SEE EXTRA OPTIONS AVAILABLE IN MODE 2\n"
  1243. "OR ANY OTHER KEY TO FINISH.\n");
  1244. }
  1245. if(getch()=='2') {
  1246. fprintf(stderr,
  1247. "MODE 2 ONLY: Additional parameters.\n"
  1248. "\n"
  1249. "CNTRE Channel from which stereo-image spreads out.\n"
  1250. "FRNT Output leading edge: 1 = in cntr lspkr: -1= in lspkr opposite cntr.\n"
  1251. " 0 = on bisector of entire sound-surround space.\n"
  1252. " 2 = infinitely far away in direction of centre,\n"
  1253. " -(2+(depth*2)) = infinitely far away in direction opposite to centre.\n"
  1254. " If front moves, forward movement only (no reversals of direction)\n"
  1255. " and if doesn't go to infinity, event itself fades to 0 from midtime.\n"
  1256. "DEPTH maximum fraction of all output chans turned on, behind front.\n"
  1257. "ROLLOFF level fall as signal is spread over several chans. Range 0-1.\n"
  1258. " 0 = no fall in level, 1 = level divided by number of chans in use.\n"
  1259. "ATTEN Level Attenuation factor for distance, or sound fade-out.\n"
  1260. " (Range >= 1 : 1 = linear).\n"
  1261. "ZPOINT Point where image subtends zero angle(mono): 0 circle edge, 1 infinity\n"
  1262. "CONTRACT Contraction factor narrowing distant image width (>=1 : 1= linear).\n"
  1263. "LOPNT Distance where lopas-filtering is total ( 0 circle edge, 1 infinity.\n"
  1264. "FMIX Factor for mixing lopas-filtrd signal into orig, with distance (>=1).\n"
  1265. "FFREQ Lo-pass filter cut-off frequency.\n"
  1266. "UP If NOT zero, proportion of overall dur over which event fades from 0.\n"
  1267. " This is independent of any fadeup-with-approach-to-circle.\n"
  1268. "DN If NOT zero, proportion of overall dur over which event fades to 0.\n"
  1269. " This is independent of any fadeout-with-distance-from-circle.\n"
  1270. "GAIN Overall gain (0-1). If \"contract\" is very much faster than \"atten\",\n"
  1271. " rare possibility of overload, as signal is forced to mono.\n"
  1272. "-z Permit stacking of very short events. Default = forbid, prevent clipping.\n"
  1273. "\n"
  1274. "in MODE 2, of the additional parameters, only \"frnt\" can vary in time.\n");
  1275. }
  1276. } else
  1277. fprintf(stdout,"Unknown option '%s'\n",str);
  1278. return(USAGE_ONLY);
  1279. }
  1280. int usage3(char *str1,char *str2)
  1281. {
  1282. fprintf(stderr,"Insufficient parameters on command line.\n");
  1283. return(USAGE_ONLY);
  1284. }
  1285. /******************************** FRACTURE *******************************/
  1286. int fracture(int ibuflen,int envbuflen,int overflow,dataptr dz)
  1287. {
  1288. int exit_status, chans, tim, lev, stim, etim, toget, thistack, filter_state = 0, dostack;
  1289. double srate = (double)dz->infile->srate, maxsamp = 0.0, normaliser;
  1290. int n, m, total_samps_written = 0, end_read_buf_at = -1, start_read_buf_at = 0;
  1291. int strmcnt = dz->iparam[FRAC_STRMS];
  1292. /*
  1293. * LONG ARRAYS: S = number of streams iptr (start of read WITHIN current input buffer, for each stream)
  1294. * | temp storage of event starttimes
  1295. * |---------------|---------------| | |
  1296. * | segendsamp | inreadsamp | | | NB segendsamp is in MONO samps
  1297. * address 0 S 2S| | need to change to (segendsamp * chans)
  1298. * | | | 2S+1 + lmost(rmost) % dz->buflen
  1299. * array | maxevents | maxevents | | | for write!!
  1300. * length | | strmcnt
  1301. * | | | strmcnt
  1302. */
  1303. int **evend = dz->lparray, **iread = dz->lparray + strmcnt; // Event endtime & input-read position, for each \fragment in each stream in each event-group
  1304. int *iptr = dz->lparray[2*strmcnt]; // Pointers into input buffer, for each stream in current event-group
  1305. int *evstt = dz->lparray[(2*strmcnt)+1]; // Envelope starttime in each stream in current event-group
  1306. /*
  1307. * DOUBLE ARRAYS: S = number of streams | llev
  1308. * | | | rlev
  1309. * |---------------|---------------|---------------|---------------|---------------| | pos
  1310. * | depth | level | transpos | envreadtime | stacking | | | tempenv
  1311. * | | | | | 5S| | | envdata
  1312. * | | | | | | 5S+1| | stakcentre
  1313. * address 0 S 2S 3S 4S | | 5S+2| | grptimes
  1314. * | | | | | | | | 5S+3| | |
  1315. * | | | | | | | | | 5S+4| |
  1316. * array | maxevents | maxevents | maxevents | maxevents | maxevents | | | | | 5S+5|
  1317. * length | | | | | S S S | | | 5S+6
  1318. * | | | | | | | | 14| | | |
  1319. * | | | | | | | | | dz->envcount * 15
  1320. * | | | | | | | | | | S | |
  1321. * | | | | | | | | | | | maxevents
  1322. */
  1323. double **depth = dz->parray; // Envelope (end) depth for each event in each stream
  1324. double **evlev = dz->parray + strmcnt; // Level for each event in each stream
  1325. double **evpch = dz->parray + (2 * strmcnt); // Transposition for each event in each stream
  1326. double **eread = dz->parray + (3 * strmcnt); // Position to read envelope table for each event in each stream
  1327. double **stakk = dz->parray + (4 * strmcnt); // Stacking value for each event in each stream
  1328. double *llev = dz->parray[5 * strmcnt], *rlev = dz->parray[(5 * strmcnt)+1]; // Left and Right level for each stream, to create correct positioning
  1329. double *tempenv = dz->parray[dz->envbuf]; // Temporary envelope store
  1330. double *stkcntr = dz->parray[(5 * strmcnt)+5]; // Central peak of current envelope for each stream
  1331. double *gptime = dz->parray[(5 * strmcnt)+6]; // group-Timing of events (for reading brktables)
  1332. /*
  1333. * INTEGER ARRAYS: S = number of streams
  1334. *
  1335. * lmost
  1336. * | rmost
  1337. * | | |
  1338. * address 0 1 |
  1339. * | | |
  1340. * array S S |
  1341. * length | | |
  1342. */
  1343. int *lmost = dz->iparray[0], *rmost = dz->iparray[1]; // Left & right lspkr for each stream
  1344. /*
  1345. * SOUND BUFFERS
  1346. * | input | enveloping| stacking | output | overflow |
  1347. *
  1348. */
  1349. float *ibuf = dz->sampbuf[0];
  1350. float *ebuf = dz->sampbuf[1];
  1351. float *stkbuf= dz->sampbuf[2];
  1352. float *obuf = dz->sampbuf[3];
  1353. float *ovflw = dz->sampbuf[4];
  1354. int write_end = 0;
  1355. double gp_stependtime = 0.0, last_gp_stependtime = 0.0, time, endtime, readtime;
  1356. double init_depth, startdepth, enddepth, depthchange, thisdepth;
  1357. double gp_stepdur, last_gp_stepdur = 0.0, randscat, maxeoffset, stack, this_stack, level, lbas, tdiff, ldiff, eval, frac;
  1358. double transpos, incr, dsampcnt, loval, hival, diff, val, levrand, outincr, dipos, centre = 0.0;
  1359. int losamp, hisamp, sectcnt = 0, cntrswitch = 0, outside = 0;
  1360. int evcnt = 0, total_evcnt, minevstt, minread = 0, maxread = 0, ldur, sampcnt, stakwrite_at, opos, lpos, rpos, samps_to_write, iposlo, iposhi;
  1361. int samps_to_read, samps_read, this_write_end, evlen, endevent, endeventend, fracmax = 0, endzeros = 0, samps_to_process;
  1362. int display_limit = 2 * dz->infile->srate, this_display_limit = display_limit;
  1363. double maxscatrange, lastev, offset, scatter_ambit_stt, scatter_ambit_end, available_dur, spread = 0.0, fmix = 0.0, prand;
  1364. if(dz->mode == 0)
  1365. chans = dz->iparam[FRAC_CHANS];
  1366. else
  1367. chans = STEREO; // Process initially creates stereo image which is then dispersed over multichannel space
  1368. fprintf(stdout,"INFO: Level Check at %lf secs\n",(double)(total_samps_written/chans)/srate);
  1369. fflush(stdout);
  1370. while(gp_stependtime < dz->duration) {
  1371. time = gp_stependtime; // Set start-time to end of last GROUP step
  1372. gptime[evcnt] = time;
  1373. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  1374. return exit_status;
  1375. if(dz->param[FRAC_MAX] > 0.0 && dz->param[FRAC_MIN] >= dz->param[FRAC_MAX]) {
  1376. sprintf(errstr,"Max (%lf) and min (%lf) fragment-lengths incompatible at %lf secs\n",
  1377. dz->param[FRAC_MIN],dz->param[FRAC_MAX],time);
  1378. return DATA_ERROR;
  1379. }
  1380. dz->iparam[FRAC_MAX] = (int)ceil(dz->param[FRAC_MAX] * srate);
  1381. init_depth = dz->param[FRAC_DEPTH]; // Initial depth retained here for first event
  1382. // SET THE STREAMS-GROUP END-POSITION, POSSIBLY RANDOMISED
  1383. gp_stepdur = dz->param[FRAC_PULSE]; // Get duration of this step
  1384. if(dz->param[FRAC_OUTRND] > 0.0) { // If ness, random scatter this
  1385. randscat = (drand48() * 2.0) - 1.0; // Range -1 to +1
  1386. randscat *= gp_stepdur/2.0; // Range (1/2*stepdur) to (3/2*stepdur)
  1387. gp_stepdur += randscat; // Modify grp-stepdur
  1388. }
  1389. gp_stependtime = time + gp_stepdur; // This will be start of next event
  1390. // GET THE EVENT START AND END WRITE POSITIONS FOR EACH STREAM (POSSIBLT SCATTERED)
  1391. for(n=0;n<strmcnt;n++) { // Note the start sample of events in each stream
  1392. if(evcnt == 0)
  1393. evstt[n] = 0; // First events start at file start
  1394. else // Later events start where previous stream-event ended
  1395. evstt[n] = evend[n][evcnt-1];
  1396. }
  1397. maxscatrange = gp_stepdur/2.0; // Max range (+ve or -ve) over which events can be scattered
  1398. for(n=0;n<strmcnt;n++) { // Get the output end-timings of the streams
  1399. endtime = gp_stependtime; // Do scattering, if required
  1400. if(dz->param[FRAC_SCAT] > 0.0) { // Around the (already rand-offset) end-timing of the group
  1401. if(dz->param[FRAC_MIN] > 0.0) {
  1402. scatter_ambit_stt = gp_stependtime - maxscatrange;
  1403. scatter_ambit_end = gp_stependtime + maxscatrange;
  1404. if(evcnt == 0)
  1405. lastev = 0.0;
  1406. else
  1407. lastev = (evend[n][evcnt-1])/srate; // End time of previous event
  1408. available_dur = scatter_ambit_end - lastev;
  1409. if(available_dur <= dz->param[FRAC_MIN]) { // If insufficient space for min-dur fragment
  1410. if(evcnt == 0)
  1411. evend[n][evcnt] = 0;
  1412. else
  1413. evend[n][evcnt] = evend[n][evcnt-1]; // Reduce event length to zero i.e. eliminate the event
  1414. continue;
  1415. } else {
  1416. endtime = lastev + dz->param[FRAC_MIN]; // Move base of rand-vary to min-duration point
  1417. if(endtime >= scatter_ambit_stt) { // If the min length falls inside ambit of current gp-position
  1418. available_dur -= dz->param[FRAC_MIN]; // Length to scatter-amongst is what remains
  1419. } else { // If NOT
  1420. endtime = scatter_ambit_stt; // force base into ambit of current gp-position
  1421. available_dur = maxscatrange * 2.0; // Length to scatter-amongst is whole ambit around gp-position
  1422. }
  1423. // Do randomisation within the remaining range
  1424. randscat = drand48(); // Range 0 to 1
  1425. randscat *= available_dur * dz->param[FRAC_SCAT];
  1426. }
  1427. } else {
  1428. randscat = (drand48() * 2) - 1.0; // Range -1 to 1
  1429. if(evcnt > 0) {
  1430. lastev = (evend[n][evcnt-1])/srate; // End time of previous event
  1431. offset = gp_stependtime - lastev; // Time between end of last event and current event_group centre
  1432. if(offset <= 0) { // Previous event end is beyond current gpevent-end
  1433. evend[n][evcnt] = evend[n][evcnt-1]; // Reduce event length to zero i.e. eliminate the event
  1434. continue;
  1435. } else if(offset < maxscatrange && randscat < 0.0) // If scattering DOWN, and offset smaller than maxrange
  1436. randscat *= offset * dz->param[FRAC_SCAT]; // Scatter within offset
  1437. else // In all other cases, scatter within true maxrange
  1438. randscat *= maxscatrange * dz->param[FRAC_SCAT];
  1439. } else
  1440. randscat *= maxscatrange * dz->param[FRAC_SCAT];
  1441. }
  1442. endtime += randscat; // Use the actual group step-position as basis to calc rand-offsets
  1443. }
  1444. evend[n][evcnt] = (int)round(endtime * srate);
  1445. }
  1446. // DECIDE IF A WRITE-OUTBUF IS REQUIRED, AND IF SO, DO IT
  1447. minevstt = evstt[0]; // Find minimum event start
  1448. for(n=1;n<strmcnt;n++)
  1449. minevstt = min(minevstt,evstt[n]);
  1450. minevstt *= chans; // Convert to frame of output (has more channels)
  1451. minevstt -= total_samps_written; // Convert to frame of output-buffer
  1452. if(minevstt >= dz->buflen) { // If next write will start at or after buffer end
  1453. if(total_samps_written/chans > this_display_limit) {
  1454. fprintf(stdout,"INFO: Level Check at %lf secs\n",(double)(total_samps_written/chans)/srate);
  1455. fflush(stdout);
  1456. this_display_limit += display_limit;
  1457. }
  1458. for(n=0;n < dz->buflen;n++) // "Write", copy overflow back, zero overflow
  1459. maxsamp = max(maxsamp,fabs(obuf[n]));
  1460. total_samps_written += dz->buflen;
  1461. write_end -= dz->buflen;
  1462. for(n = 0;n < write_end;n++) // Copy back overflow into obuf (overflow may be longer than obuf)
  1463. obuf[n] = ovflw[n]; // and zero remainder of overflow
  1464. memset((char *)(obuf+write_end),0,(dz->buflen + overflow - write_end) * sizeof(float));
  1465. }
  1466. // FIND END DEPTH OF EACH STREAM
  1467. for(n=0;n<strmcnt;n++) {
  1468. endtime = (double)(evend[n][evcnt])/srate; // Get true endtime of stream-event
  1469. if(dz->brksize[FRAC_DEPTH]) {
  1470. if((exit_status = read_value_from_brktable(endtime,FRAC_DEPTH,dz))<0)
  1471. return(exit_status); // And read depth at end of event
  1472. }
  1473. depth[n][evcnt] = dz->param[FRAC_DEPTH];
  1474. }
  1475. // FIND READ SAMPLE OF EACH STREAM, (RANDOMISED IF REQUIRED) AND MAX AND MINIMUM READ
  1476. if(evcnt == 0) { // At very start, all segments are read at 0
  1477. for(n=0;n<strmcnt;n++)
  1478. iread[n][evcnt] = 0;
  1479. minread = 0;
  1480. maxread = 0;
  1481. for(n=0;n<strmcnt;n++)
  1482. maxread = max(maxread,evend[n][evcnt]);
  1483. startdepth = init_depth; // Depth already read at start of loop
  1484. enddepth = depth[n][evcnt];
  1485. if(startdepth < 1 || enddepth < 1) // If envelopes don't cut down to zero at both ends
  1486. fracmax = 0;
  1487. else
  1488. fracmax = dz->iparam[FRAC_MAX];
  1489. } else {
  1490. for(n=0;n<strmcnt;n++) { // Scatter the output read-timings for the streams (if ness)
  1491. startdepth = depth[n][evcnt - 1]; // Startdepth = previous end-depth
  1492. enddepth = depth[n][evcnt];
  1493. if(startdepth < 1 || enddepth < 1) { // If envelopes don't cut down to zero at both ends
  1494. iread[n][evcnt] = evend[n][evcnt - 1]; // reads & writes in same place, avoid discontinuity in output sig
  1495. fracmax = 0;
  1496. } else {
  1497. readtime = last_gp_stependtime;
  1498. if(dz->param[FRAC_INRND] > 0) {
  1499. randscat = (drand48() * 2) - 1.0; // Around the timing START of the group
  1500. randscat *= (last_gp_stepdur/2.0) * dz->param[FRAC_INRND];
  1501. readtime += randscat;// Using the actual group step-duration as basis to calc rand offsets
  1502. }
  1503. iread[n][evcnt] = (int)round(readtime * srate);
  1504. fracmax = dz->iparam[FRAC_MAX];
  1505. }
  1506. evlen = evend[n][evcnt] - evend[n][evcnt-1];
  1507. if(fracmax > 0)
  1508. evlen = min(evlen,fracmax);
  1509. if(n==0) {
  1510. minread = iread[n][evcnt];
  1511. maxread = iread[n][evcnt] + evlen;
  1512. } else {
  1513. minread = min(iread[n][evcnt],minread);
  1514. maxread = max(iread[n][evcnt] + evlen,maxread);
  1515. }
  1516. }
  1517. }
  1518. // SEARCH TO APPROPRIATE PLACE IN INPUT, AND SET IPTRS
  1519. if(maxread - minread > ibuflen) {
  1520. sprintf(errstr,"INPUT BUFFERSIZE MISCALCULATION\n");
  1521. return(PROGRAM_ERROR);
  1522. }
  1523. if(maxread > end_read_buf_at) {
  1524. sndseekEx(dz->ifd[0],minread,0);
  1525. start_read_buf_at = minread;
  1526. samps_to_read = maxread - minread;
  1527. memset((char *)ibuf,0,ibuflen * sizeof(float));
  1528. if((samps_read = fgetfbufEx(ibuf,ibuflen,dz->ifd[0],0))<0) {
  1529. sprintf(errstr,"Sound read error: %s\n",sferrstr());
  1530. return(SYSTEM_ERROR);
  1531. }
  1532. if(samps_read < samps_to_read) {
  1533. fprintf(stdout,"INFO: Ran out of input samples: Terminating.\n");
  1534. fflush(stdout);
  1535. break;
  1536. }
  1537. end_read_buf_at = start_read_buf_at + samps_read;
  1538. }
  1539. for(n=0;n<strmcnt;n++)
  1540. iptr[n] = iread[n][evcnt] - start_read_buf_at;
  1541. // FIND THE TIMES AT WHICH TO READ ENVELOPE-TEMPLATE, AND THE DEPTH
  1542. if(evcnt == 0) { // At very start, all envelope are read at 0
  1543. for(n=0;n<strmcnt;n++)
  1544. eread[n][evcnt] = 0.0;
  1545. } else { // Otherwise,
  1546. for(n=0;n<strmcnt;n++) { // initially set envelope read position to start of segment, for each stream
  1547. eread[n][evcnt] = (double)(evend[n][evcnt - 1])/srate;
  1548. if(dz->param[FRAC_ENVRND] > 0.0) { // If the envelope reading is scattered over a time-range
  1549. maxeoffset = min(dz->param[FRAC_ENVRND],eread[n][evcnt]);
  1550. randscat = drand48() * maxeoffset; // Check timerange does not exceed "now"
  1551. eread[n][evcnt] -= randscat; // Then generate randomisation of read position
  1552. }
  1553. }
  1554. }
  1555. for(n=0;n<strmcnt;n++) { // Find depth at end of each stream
  1556. endtime = (double)(evend[n][evcnt])/srate; // Get true endtime of stream-event
  1557. if(dz->brksize[FRAC_DEPTH]) {
  1558. if((exit_status = read_value_from_brktable(endtime,FRAC_DEPTH,dz))<0)
  1559. return(exit_status); // And read depth at end of event
  1560. }
  1561. depth[n][evcnt] = dz->param[FRAC_DEPTH];
  1562. }
  1563. // READ ENVELOPE-TEMPLATE, MODIFY DEPTHS AND TIMINGS (AND CHECK FOR STACKING)
  1564. for(n=0;n<strmcnt;n++) { // Reads an envelope template at specified time, and modify
  1565. read_the_envelope(eread[n][evcnt],dz); // Read from input data-envelopes to temp envelope-store "tempenv"
  1566. stkcntr[n] = getstakcentre(tempenv,dz); // Note where the peak is, for any stacking
  1567. // Get envelope depth+stacking value
  1568. if(evcnt == 0) // At very start
  1569. startdepth = init_depth; // Depth already read at start of loop
  1570. else // Else
  1571. startdepth = depth[n][evcnt - 1]; // Startdepth = previous end-depth
  1572. enddepth = depth[n][evcnt];
  1573. stack = 0;
  1574. if(startdepth >= 1.0 && enddepth >= 1.0) {
  1575. // If depth values beyond 1, this represents stacking.
  1576. stack = startdepth - 1.0; // Derive stacking value from depth at start of event.
  1577. startdepth = 1.0; // and reset depth values to depth-maxima (1.0)
  1578. enddepth = 1.0; // NB Both depths must be 1, so envelope edges tied to zero, so stack causes no glitches
  1579. } else {
  1580. // If depths is not everywhere at max, interp depth data onto env
  1581. depthchange = enddepth - startdepth;
  1582. for(tim=0,lev=1;tim<14;tim+=2,lev+=2) {
  1583. thisdepth = depthchange * tempenv[tim]; // Times are between 0 and 1, so time also represents FRACTION of time
  1584. thisdepth += startdepth;
  1585. if(thisdepth > 1.0)
  1586. thisdepth = 1.0;
  1587. level = 1.0 - thisdepth; // Max Depth = min env level depth 1 -> 0 level| depth 1/3 -> level2/3| depth 0 -> level 1
  1588. level += (tempenv[lev] * thisdepth);// Env fills remaining space i.e whole space | upper 1/3 of space: | None of space, env has no effect
  1589. tempenv[lev] = level;
  1590. }
  1591. }
  1592. // COPY APPROPRIATE INPUT SAMPLES TO ENVELOPE BUFFER, AND DO ENVELOPING
  1593. if(evcnt == 0)
  1594. ldur = evend[n][0];
  1595. else
  1596. ldur = evend[n][evcnt] - evend[n][evcnt-1];
  1597. if(fracmax > 0)
  1598. ldur = min(ldur,fracmax);
  1599. if(ldur > envbuflen) {
  1600. sprintf(errstr,"ENVELOPE BUFFERSIZE MISCALCULATION: required sample duration = %d available envelope buffer length = %d\n",ldur,envbuflen);
  1601. return(PROGRAM_ERROR);
  1602. }
  1603. memset((char *)ebuf,0,envbuflen * sizeof(float));
  1604. memcpy((char *)ebuf,(char *)(ibuf + iptr[n]),ldur * sizeof(float));
  1605. stim = 0;
  1606. etim = 2;
  1607. lbas = tempenv[stim+1]; // Start of envelope segment
  1608. tdiff = tempenv[etim] - tempenv[stim]; // Timestep in envelope segment
  1609. ldiff = tempenv[etim+1] - tempenv[stim+1]; // Level step in envelope segment
  1610. for(sampcnt=0;sampcnt<ldur;sampcnt++) {
  1611. eval = tempenv[13]; // Default to end value, in case we run off end of table
  1612. if(etim < 14) {
  1613. toget = 1;
  1614. frac = (double)sampcnt/(double)ldur; // Find time-fraction
  1615. while(frac > tempenv[etim]) { // Locate which envelope seg we're in
  1616. stim = etim; // advancing to next where ness
  1617. etim += 2;
  1618. if(etim >= 14) { // Gets default value at table end
  1619. toget = 0;
  1620. break;
  1621. } else {
  1622. lbas = tempenv[stim+1]; // and resetting segment constants
  1623. tdiff = tempenv[etim] - tempenv[stim];
  1624. ldiff = tempenv[etim+1] - tempenv[stim+1];
  1625. }
  1626. }
  1627. if(toget) { // Interp in envelope table
  1628. eval = (frac - tempenv[stim])/tdiff;
  1629. eval *= ldiff;
  1630. eval += lbas;
  1631. }
  1632. } // Use envelope val to scale input
  1633. ebuf[sampcnt] = (float)(ebuf[sampcnt] * eval);
  1634. }
  1635. // IF STACKING - IF STACKING RANDOMISED SET A STACK VALUE - STORE STACKING VALUE
  1636. if(stack > 0) {
  1637. dostack = 1;
  1638. if(ldur < 8192) { // Prevent stacking of very short events
  1639. if(!dz->vflag[0]) { // Unless allowed
  1640. dostack = 0;
  1641. stack = 0;
  1642. }
  1643. }
  1644. if (dostack) {
  1645. if(dz->param[FRAC_STKRND] > 0) {
  1646. this_stack = stack;
  1647. stack *= drand48() * dz->param[FRAC_STKRND];
  1648. stack = this_stack - stack;
  1649. }
  1650. }
  1651. }
  1652. stakk[n][evcnt] = stack; // Store stack values for next pass
  1653. if(stack > 0) {
  1654. memset((char *)stkbuf,0,envbuflen * sizeof(float));
  1655. thistack = (int)floor(stack); // e.g. 2.0 e.g. 2.3
  1656. while(thistack > 0) { // --> 2 --> 2
  1657. if(flteq((double)thistack,stack))
  1658. level = 1.0; // level 1
  1659. // trans remains 2
  1660. else {
  1661. level = stack - (double)thistack; // level 0.3
  1662. thistack++; // trans 3
  1663. }
  1664. transpos = dz->param[FRAC_STACK] * thistack; // Derives stacking interval from multiple of stack parameter
  1665. incr = pow(2.0,(transpos/SEMITONES_PER_OCTAVE)); // semitones to frq ratio
  1666. stakwrite_at = getstakwritestt(stkcntr[n],ldur,incr); // Find where to start writing this particular transposition into stakbuf
  1667. dsampcnt = 0.0;
  1668. while(dsampcnt < ldur) { // Read the enveloped orig, with an incr that transposes it
  1669. losamp = (int)floor(dsampcnt); // Interpolating as ness
  1670. hisamp = losamp+1;
  1671. frac = dsampcnt - (double)losamp;
  1672. loval = ebuf[losamp];
  1673. hival = ebuf[hisamp];
  1674. diff = hival - loval;
  1675. diff *= frac;
  1676. val = loval + diff; // Add the interpd val into stakbuffer
  1677. stkbuf[stakwrite_at] = (float)(stkbuf[stakwrite_at] + val); // (There may be more than 1 stack component to add)
  1678. stakwrite_at++; // Incr normally in stacking buffer
  1679. dsampcnt += incr; // Incr transpositionwise in read-from buff
  1680. }
  1681. thistack--; // -->1 --> 1
  1682. stack = (double)thistack; // Will now generate full level for lower stack components
  1683. }
  1684. // Once all staks generated, add stacks to original envelope buffer
  1685. for(m=0;m<ldur;m++)
  1686. ebuf[m] = (float)(ebuf[m] + stkbuf[m]);
  1687. }
  1688. // IF LEVEL IS RANDOMISED, AND EVENTS ARE FULLY SEPARATED (Depth 1 at both ends) GET A RANDOM LEVEL AND APPLY IT
  1689. if(startdepth >= 1.0 && enddepth >= 1.0) { // Level or pitch-shifting can only happem
  1690. if(dz->param[FRAC_LEVRND] > 0) { // if edges of event are tied to zero-level
  1691. levrand = drand48() * dz->param[FRAC_LEVRND];
  1692. levrand = 1.0 - levrand;
  1693. evlev[n][evcnt] = levrand;
  1694. for(m=0;m<ldur;m++)
  1695. ebuf[m] = (float)(ebuf[m] * evlev[n][evcnt]);
  1696. } else
  1697. evlev[n][evcnt] = 1.0;
  1698. // IF PITCH IS RANDOMISED, GET A RANDOM PITCH-INCR READY TO READ ENVELOPED DATA TO OUTPUT BUFFER
  1699. // IF NOT, THIS GETS VALUE 1 (No pitch change)
  1700. if(dz->param[FRAC_PCHRND] > 0) {
  1701. prand = drand48() * dz->param[FRAC_PCHRND];
  1702. outincr = pow(2.0,(prand/SEMITONES_PER_OCTAVE)); // Convert from semitones to frq-ratio
  1703. } else
  1704. outincr = 1.0;
  1705. evpch[n][evcnt] = outincr; // Store
  1706. } else {
  1707. evlev[n][evcnt] = 1.0;
  1708. evpch[n][evcnt] = 1.0;
  1709. outincr = 1.0;
  1710. }
  1711. // SAFETY CHECK FOR OUTPUT BUFFER OVERFLOW
  1712. opos = evstt[n] * chans; // Change write position to frame of output
  1713. opos -= total_samps_written; // Change write position to frame of output-buffer
  1714. samps_to_write = (int)ceil((double)ldur/outincr) * chans;
  1715. if(samps_to_write + opos >= dz->buflen + overflow) {
  1716. sprintf(errstr,"OVERFLOW BUFFER ITSELF OVERFLOWED WHEN PITCH INCR WAS %lf.\n",outincr);
  1717. return(PROGRAM_ERROR);
  1718. }
  1719. // WRITE OUTPUT
  1720. lpos = opos + lmost[n]; // Change write position to correct left and right channels
  1721. rpos = opos + rmost[n];
  1722. dipos = 0.0;
  1723. while(dipos < ldur) { // This should wraparound OK, as buffer is preset with zeros
  1724. iposlo = (int)floor(dipos); // So wraparound sample will be zero
  1725. iposhi = iposlo+1;
  1726. frac = dipos - (double)iposlo;
  1727. loval = ebuf[iposlo];
  1728. hival = ebuf[iposhi];
  1729. diff = hival - loval;
  1730. diff *= frac;
  1731. val = loval + diff; // Add the interpd enveloped-val into output buffer
  1732. obuf[lpos] = (float)(obuf[lpos] + (val * llev[n]));
  1733. obuf[rpos] = (float)(obuf[rpos] + (val * rlev[n]));
  1734. dipos += outincr; // Interpolate in input (enveloped) sound
  1735. lpos += chans; // Jump by a whole channel-group in output buffer
  1736. rpos += chans;
  1737. }
  1738. this_write_end = (lpos/chans) * chans; // Round up to end of last-group written, to find end of write in buffer
  1739. write_end = max(this_write_end,write_end); // Find write_end from all stream writes (and previous writes)
  1740. }
  1741. // ONCE ALL STREAMS ADDED TO OUTPUT
  1742. evcnt++; // Count event
  1743. last_gp_stependtime = gp_stependtime; // Remember startsamp and sampduration of previous group-segment
  1744. last_gp_stepdur = gp_stepdur; // Need for generating input-read time
  1745. }
  1746. total_evcnt = evcnt;
  1747. if(write_end > 0) {
  1748. fprintf(stdout,"INFO: Level Check at %lf secs\n",(double)(total_samps_written/chans)/srate);
  1749. fflush(stdout);
  1750. for(n=0;n < write_end;n++) // "Write", copy overflow back, zero overflow
  1751. maxsamp = max(maxsamp,fabs(obuf[n]));
  1752. total_samps_written += write_end;
  1753. }
  1754. normaliser = 1.0;
  1755. if(maxsamp > 0.95) {
  1756. normaliser = 0.95/maxsamp;
  1757. fprintf(stdout,"INFO: Normalising by %lf secs\n",(double)normaliser);
  1758. fflush(stdout);
  1759. }
  1760. for(n=0;n<strmcnt;n++) { // In each stream
  1761. endevent = evcnt-1; // Find the last active event
  1762. endeventend = evend[n][endevent]; // i.e. last event NOT of zero length
  1763. m = endevent - 1;
  1764. while(m >= 0) {
  1765. if(evend[n][m] < endeventend) // If previous event begins earlier, we've found end event
  1766. break;
  1767. else { // Else end of two events coincides, thus zero-length event.
  1768. endevent = m; // Skip back over it,to find real last-active-event
  1769. m--;
  1770. }
  1771. }
  1772. depth[n][endevent] = 1; // Force this last event to fade to zero at stream's end
  1773. }
  1774. fprintf(stdout,"INFO: Second pass: generating output.\n");
  1775. fflush(stdout);
  1776. if(sloom) {
  1777. if(dz->mode == 0)
  1778. dz->insams[0] = total_samps_written; // This forces sloom progress bar to proceed correctly, without mod to libraries
  1779. else
  1780. dz->insams[0] = (total_samps_written/STEREO) * dz->iparam[FRAC_CHANS];
  1781. }
  1782. sndseekEx(dz->ifd[0],0,0);
  1783. reset_filedata_counters(dz);
  1784. memset((char *)obuf,0,(dz->buflen + overflow) * sizeof(float)); // reset output and overflow buffers
  1785. memset((char *)ibuf,0,ibuflen * sizeof(float)); // reset input buffer
  1786. total_samps_written = 0;
  1787. end_read_buf_at = -1;
  1788. start_read_buf_at = 0;
  1789. write_end = 0;
  1790. evcnt = 0;
  1791. while(evcnt < total_evcnt) {
  1792. time = gptime[evcnt]; // Set start-time to end of last GROUP step
  1793. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  1794. return exit_status;
  1795. dz->iparam[FRAC_MAX] = (int)ceil(dz->param[FRAC_MAX] * srate);
  1796. init_depth = dz->param[FRAC_DEPTH];
  1797. // GET THE EVENT START POSITIONS FOR EACH STREAM
  1798. for(n=0;n<strmcnt;n++) { // Note the start sample of events in each stream
  1799. if(evcnt == 0)
  1800. evstt[n] = 0;
  1801. else
  1802. evstt[n] = evend[n][evcnt-1];
  1803. }
  1804. // DECIDE IF A WRITE-OUTBUF IS REQUIRED, AND IF SO, DO IT
  1805. minevstt = evstt[0]; // Find minimum event start
  1806. for(n=1;n<strmcnt;n++)
  1807. minevstt = min(minevstt,evstt[n]);
  1808. minevstt *= chans; // Convert to frame of output (has more channels)
  1809. minevstt -= total_samps_written; // Convert to frame of output-buffer
  1810. if(minevstt >= dz->buflen) { // If next write will start at or after buffer end
  1811. for(n=0;n < dz->buflen;n++) // Normalise, write output, copy overflow back, zero overflow
  1812. obuf[n] = (float)(obuf[n] * normaliser);
  1813. if(dz->mode == 0) {
  1814. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1815. return(exit_status);
  1816. total_samps_written += dz->buflen;
  1817. write_end -= dz->buflen;
  1818. for(n = 0;n < write_end;n++) // Copy back overflow into obuf (overflow may be longer than obuf)
  1819. obuf[n] = ovflw[n]; // and zero remainder of overflow
  1820. memset((char *)(obuf+write_end),0,(dz->buflen + overflow - write_end) * sizeof(float));
  1821. } else {
  1822. samps_to_process = dz->buflen;
  1823. if(dz->fltractv) {
  1824. if((exit_status = filter_process(&samps_to_process,&endzeros,dz))<0)
  1825. return(exit_status);
  1826. }
  1827. if((exit_status = panspread(&sectcnt,&centre,&spread,&cntrswitch,&outside,&fmix,samps_to_process,dz))<0)
  1828. return(exit_status);
  1829. if(exit_status == CONTINUE) {
  1830. total_samps_written += dz->buflen;
  1831. write_end -= dz->buflen;
  1832. for(n = 0;n < write_end;n++) // Copy back overflow into obuf (overflow may be longer than obuf)
  1833. obuf[n] = ovflw[n]; // and zero remainder of overflow
  1834. memset((char *)(obuf+write_end),0,(dz->buflen + overflow - write_end) * sizeof(float));
  1835. } else {
  1836. write_end = 0;
  1837. break;
  1838. }
  1839. }
  1840. }
  1841. // FIND READ SAMPLE OF EACH STREAM, AND MAX AND MINIMUM READ
  1842. if(evcnt == 0) { // At very start, all segments are read at 0
  1843. minread = 0;
  1844. maxread = 0;
  1845. for(n=0;n<strmcnt;n++)
  1846. maxread = max(maxread,evend[n][evcnt]);
  1847. startdepth = init_depth; // Startdepth = previous end-depth
  1848. enddepth = depth[n][evcnt];
  1849. if(startdepth < 1 || enddepth < 1) // If envelopes don't cut down to zero at both ends
  1850. fracmax = 0; // Max fragment length not used
  1851. else
  1852. fracmax = dz->iparam[FRAC_MAX];
  1853. } else {
  1854. for(n=0;n<strmcnt;n++) { // Scatter the output read-timings for the streams (if ness)
  1855. startdepth = depth[n][evcnt - 1]; // Startdepth = previous end-depth
  1856. enddepth = depth[n][evcnt];
  1857. if(startdepth < 1 || enddepth < 1) // If envelopes don't cut down to zero at both ends
  1858. fracmax = 0; // Max fragment length not used
  1859. else
  1860. fracmax = dz->iparam[FRAC_MAX];
  1861. evlen = evend[n][evcnt] - evend[n][evcnt-1];
  1862. if(fracmax > 0)
  1863. evlen = min(evlen,fracmax);
  1864. if(n==0) {
  1865. minread = iread[n][evcnt];
  1866. maxread = iread[n][evcnt] + evlen;
  1867. } else {
  1868. minread = min(iread[n][evcnt],minread);
  1869. maxread = max(iread[n][evcnt] + evlen,maxread);
  1870. }
  1871. }
  1872. }
  1873. // SEARCH TO APPROPRIATE PLACE IN INPUT (IF NECESSARY), AND SET IPTRS
  1874. if(maxread > end_read_buf_at) {
  1875. sndseekEx(dz->ifd[0],minread,0);
  1876. start_read_buf_at = minread;
  1877. samps_to_read = maxread - minread;
  1878. if((samps_read = fgetfbufEx(ibuf,ibuflen,dz->ifd[0],0))<0) {
  1879. sprintf(errstr,"Sound read error: %s\n",sferrstr());
  1880. return(SYSTEM_ERROR);
  1881. }
  1882. if(samps_read < samps_to_read) {
  1883. fprintf(stdout,"WARNING: Sound Read anomaly - short buffer read, probably at end of file: Terminating.\n");
  1884. fflush(stdout); // This shouled not happen as it's trapped on the first pass
  1885. break;
  1886. }
  1887. end_read_buf_at = start_read_buf_at + samps_read;
  1888. }
  1889. for(n=0;n<strmcnt;n++)
  1890. iptr[n] = iread[n][evcnt] - start_read_buf_at;
  1891. // READ ENVELOPE-TEMPLATE, MODIFY DEPTHS AND TIMINGS (AND CHECK FOR STACKING)
  1892. for(n=0;n<strmcnt;n++) { // Reads and envelope template at specified time, and modify
  1893. read_the_envelope(eread[n][evcnt],dz); // Read from input data-envelopes to temp envelope-store "tempenv"
  1894. stkcntr[n] = getstakcentre(tempenv,dz); // Note where the peak is, for any stacking
  1895. // Get envelope depth+stacking value
  1896. if(evcnt == 0) // At very start
  1897. startdepth = init_depth; // Depth already read at start of loop
  1898. else // Else
  1899. startdepth = depth[n][evcnt - 1]; // Startdepth = previous end-depth
  1900. enddepth = depth[n][evcnt];
  1901. if(startdepth >= 1.0 && enddepth >= 1.0) {
  1902. startdepth = 1.0;
  1903. enddepth = 1.0;
  1904. } else {
  1905. depthchange = enddepth - startdepth;
  1906. for(tim=0,lev=1;tim<14;tim+=2,lev+=2) {
  1907. thisdepth = depthchange * tempenv[tim]; // Times are between 0 and 1, so time also represents FRACTION of time
  1908. thisdepth += startdepth;
  1909. if(thisdepth > 1.0)
  1910. thisdepth = 1.0;
  1911. level = 1.0 - thisdepth; // Max Depth = min env level depth 1 -> 0 level| depth 1/3 -> level2/3| depth 0 -> level 1
  1912. level += (tempenv[lev] * thisdepth);// Env fills remaining space i.e whole space | upper 1/3 of space: | None of space, env has no effect
  1913. tempenv[lev] = level;
  1914. }
  1915. }
  1916. // COPY APPROPRIATE INPUT SAMPLES TO ENVELOPE BUFFER, AND DO ENVELOPING
  1917. if(evcnt == 0)
  1918. ldur = evend[n][0];
  1919. else
  1920. ldur = evend[n][evcnt] - evend[n][evcnt-1];
  1921. if(fracmax > 0)
  1922. ldur = min(ldur,fracmax);
  1923. memset((char *)ebuf,0,envbuflen * sizeof(float));
  1924. memcpy((char *)ebuf,(char *)(ibuf + iptr[n]),ldur * sizeof(float));
  1925. stim = 0;
  1926. etim = 2;
  1927. lbas = tempenv[stim+1]; // Start of envelope segment
  1928. tdiff = tempenv[etim] - tempenv[stim]; // Timestep in envelope segment
  1929. ldiff = tempenv[etim+1] - tempenv[stim+1]; // Level step in envelope segment
  1930. for(sampcnt=0;sampcnt<ldur;sampcnt++) {
  1931. eval = tempenv[13]; // Default to end value, in case we run off end of table
  1932. if(etim < 14) {
  1933. toget = 1;
  1934. frac = (double)sampcnt/(double)ldur; // Find time-fraction
  1935. while(frac > tempenv[etim]) { // Locate which envelope seg we're in
  1936. stim = etim; // advancing to next where ness
  1937. etim += 2;
  1938. if(etim >= 14) {
  1939. toget = 0;
  1940. break;
  1941. } else {
  1942. lbas = tempenv[stim+1]; // and resetting segment constants
  1943. tdiff = tempenv[etim] - tempenv[stim];
  1944. ldiff = tempenv[etim+1] - tempenv[stim+1];
  1945. }
  1946. }
  1947. if(toget) { // Interp in envelope table
  1948. eval = (frac - tempenv[stim])/tdiff;
  1949. eval *= ldiff;
  1950. eval += lbas;
  1951. }
  1952. } // Use envelope val to scale input
  1953. ebuf[sampcnt] = (float)(ebuf[sampcnt] * eval);
  1954. }
  1955. // IF STACKING - DO STACKING
  1956. stack = stakk[n][evcnt];
  1957. if(stack > 0) {
  1958. memset((char *)stkbuf,0,envbuflen * sizeof(float));
  1959. thistack = (int)floor(stack); // e.g. 2.0 e.g. 2.3
  1960. while(thistack > 0) { // --> 2 --> 2
  1961. if(flteq((double)thistack,stack))
  1962. level = 1.0; // level 1
  1963. // trans remains 2
  1964. else {
  1965. level = stack - (double)thistack; // level 0.3
  1966. transpos = dz->param[FRAC_STACK] * (1 + thistack); // trans 3
  1967. }
  1968. transpos = dz->param[FRAC_STACK] * thistack; // Derives stacking interval from multiple of stack parameter
  1969. incr = pow(2.0,(transpos/SEMITONES_PER_OCTAVE)); // semitones to frq ratio
  1970. stakwrite_at = getstakwritestt(stkcntr[n],ldur,incr); // Find where to start writing this particular transposition into stakbuf
  1971. dsampcnt = 0.0;
  1972. while(dsampcnt < ldur) { // Read the enveloped orig, with an incr that transposes it
  1973. losamp = (int)floor(dsampcnt); // Interpolating as ness
  1974. hisamp = losamp+1;
  1975. frac = dsampcnt - (double)losamp;
  1976. loval = ebuf[losamp];
  1977. hival = ebuf[hisamp];
  1978. diff = hival - loval;
  1979. diff *= frac;
  1980. val = loval + diff; // Add the interpd val into stakbuffer
  1981. stkbuf[stakwrite_at] = (float)(stkbuf[stakwrite_at] + val); // (There may be more than 1 stack component to add)
  1982. stakwrite_at++; // Incr normally in stacking buffer
  1983. dsampcnt += incr; // Incr transpositionwise in read-from buff
  1984. }
  1985. thistack--; // -->1 --> 1
  1986. stack = (double)thistack; // Will now generate full level for lower stack components
  1987. }
  1988. // Once all staks generated, add stacks to original envelope buffer
  1989. for(m=0;m<ldur;m++)
  1990. ebuf[m] = (float)(ebuf[m] + stkbuf[m]);
  1991. }
  1992. // IF LEVEL IS NOT 1.0, APPLY IT
  1993. if(!flteq(evlev[n][evcnt],1.0)) {
  1994. for(m=0;m<ldur;m++)
  1995. ebuf[m] = (float)(ebuf[m] * evlev[n][evcnt]);
  1996. }
  1997. // GET PITCH-INCR
  1998. outincr = evpch[n][evcnt];
  1999. // WRITE TO OUTPUT BUF WITH APPROPRIATE PITCHSHIFT, AND SPATIALISATION
  2000. opos = evstt[n] * chans; // Change write position to frame of output
  2001. opos -= total_samps_written; // Change write position to frame of output-buffer
  2002. lpos = opos + lmost[n]; // Change write position to correct left and right channels
  2003. rpos = opos + rmost[n];
  2004. dipos = 0.0;
  2005. while(dipos < ldur) { // This should wraparound OK, as buffer is preset with zeros
  2006. iposlo = (int)floor(dipos); // So wraparound sample will be zero
  2007. iposhi = iposlo+1;
  2008. frac = dipos - (double)iposlo;
  2009. loval = ebuf[iposlo];
  2010. hival = ebuf[iposhi];
  2011. diff = hival - loval;
  2012. diff *= frac;
  2013. val = loval + diff; // Add the interpd enveloped-val into output buffer
  2014. obuf[lpos] = (float)(obuf[lpos] + (val * llev[n]));
  2015. obuf[rpos] = (float)(obuf[rpos] + (val * rlev[n]));
  2016. dipos += outincr; // Interpolate in input (enveloped) sound
  2017. lpos += chans; // Jump by a whole channel-group in output buffer
  2018. rpos += chans;
  2019. }
  2020. this_write_end = (lpos/chans) * chans; // Round up to end of last-group written, to find end of write in buffer
  2021. write_end = max(this_write_end,write_end); // Find write_end from all stream writes (and previous writes)
  2022. }
  2023. evcnt++; // Count event
  2024. }
  2025. if(write_end > 0) {
  2026. for(n=0;n < write_end;n++) // Normalise remainder of output (ALL OF IT)
  2027. obuf[n] = (float)(obuf[n] * normaliser);
  2028. if(dz->mode == 0) { // In mode 0, write all of remaining output
  2029. if((exit_status = write_samps(obuf,write_end,dz))<0)
  2030. return(exit_status);
  2031. } else { // In mode > 0, process output in chunks of buflen samps (or less)
  2032. while(write_end > dz->buflen) {
  2033. samps_to_process = dz->buflen;
  2034. if(dz->fltractv) {
  2035. if((exit_status = filter_process(&samps_to_process,&endzeros,dz))<0)
  2036. return(exit_status);
  2037. }
  2038. if((exit_status = panspread(&sectcnt,&centre,&spread,&cntrswitch,&outside,&fmix,dz->buflen,dz))<0)
  2039. return(exit_status);
  2040. if(exit_status == CONTINUE) {
  2041. write_end -= dz->buflen;
  2042. for(n = 0;n < write_end;n++) // Copy back overflow into obuf (overflow may be longer than obuf)
  2043. obuf[n] = ovflw[n]; // and zero remainder of overflow
  2044. memset((char *)(obuf+write_end),0,(dz->buflen + overflow - write_end) * sizeof(float));
  2045. } else {
  2046. write_end = 0;
  2047. break;
  2048. }
  2049. }
  2050. if(dz->fltractv) { // In the fitered case, filter will continue to output, even if no input
  2051. samps_to_process = write_end;
  2052. do {
  2053. if((exit_status = filter_process(&samps_to_process,&endzeros,dz))<0)
  2054. return(exit_status); // Filter returns number of samples that are not (trailing) zeros
  2055. filter_state = exit_status; // & filter_state = CONTINUE if not at end of its data, or FINISHED if reached end
  2056. if(samps_to_process) { // Only spatialise data if filter outputs some data ...
  2057. if((exit_status = panspread(&sectcnt,&centre,&spread,&cntrswitch,&outside,&fmix,samps_to_process,dz))<0)
  2058. return(exit_status);
  2059. } // Quit this loop once filter runs to stream of zeros (filter_state = FINISHED)
  2060. samps_to_process = 0; // After first buffer, no samples are being sent to filter
  2061. } while(filter_state == CONTINUE);
  2062. } else if(write_end > 0) {
  2063. if((exit_status = panspread(&sectcnt,&centre,&spread,&cntrswitch,&outside,&fmix,write_end,dz))<0)
  2064. return(exit_status);
  2065. }
  2066. }
  2067. }
  2068. return FINISHED;
  2069. }
  2070. /****************************** GET_MODE *********************************/
  2071. int get_the_mode_from_cmdline(char *str,dataptr dz)
  2072. {
  2073. char temp[200], *p;
  2074. if(sscanf(str,"%s",temp)!=1) {
  2075. sprintf(errstr,"Cannot read mode of program.\n");
  2076. return(USAGE_ONLY);
  2077. }
  2078. p = temp + strlen(temp) - 1;
  2079. while(p >= temp) {
  2080. if(!isdigit(*p)) {
  2081. fprintf(stderr,"Invalid mode of program entered.\n");
  2082. return(USAGE_ONLY);
  2083. }
  2084. p--;
  2085. }
  2086. if(sscanf(str,"%d",&dz->mode)!=1) {
  2087. fprintf(stderr,"Cannot read mode of program.\n");
  2088. return(USAGE_ONLY);
  2089. }
  2090. if(dz->mode <= 0 || dz->mode > dz->maxmode) {
  2091. fprintf(stderr,"Program mode value [%d] is out of range [1 - %d].\n",dz->mode,dz->maxmode);
  2092. return(USAGE_ONLY);
  2093. }
  2094. dz->mode--; /* CHANGE TO INTERNAL REPRESENTATION OF MODE NO */
  2095. return(FINISHED);
  2096. }
  2097. /**************************** HANDLE_THE_SPECIAL_DATA ****************************/
  2098. int handle_the_special_data(char *str,dataptr dz)
  2099. {
  2100. int exit_status;
  2101. double dummy = 0.0, lasttime = 0.0, lastetime = 0.0, maxlevel = 0.0;
  2102. FILE *fp;
  2103. int cnt, linecnt;
  2104. char temp[800], *p;
  2105. if((fp = fopen(str,"r"))==NULL) {
  2106. sprintf(errstr,"Cannot open file %s to read times.\n",str);
  2107. return(DATA_ERROR);
  2108. }
  2109. linecnt = 0;
  2110. while(fgets(temp,200,fp)!=NULL) {
  2111. p = temp;
  2112. while(isspace(*p))
  2113. p++;
  2114. if(*p == ';' || *p == ENDOFSTR) // Allow comments in file
  2115. continue;
  2116. cnt = 0;
  2117. while(get_float_from_within_string(&p,&dummy)) {
  2118. switch(cnt) {
  2119. case(0):
  2120. if(linecnt == 0) {
  2121. if(dummy != 0) {
  2122. sprintf(errstr,"First time (first entry in first line) in envelopes data (%lf) must be zero.\n",dummy);
  2123. return(DATA_ERROR);
  2124. } else
  2125. lasttime = dummy;
  2126. } else {
  2127. if(dummy <= lasttime) {
  2128. sprintf(errstr,"Times (first entry) do not advance at line %d in transpositions data.\n",linecnt+1);
  2129. return(DATA_ERROR);
  2130. }
  2131. }
  2132. break;
  2133. case(1):
  2134. if(dummy != 0) {
  2135. sprintf(errstr,"First envelope time (2nd entry) (%lf) in envelope data line (%d) must be zero.\n",dummy,linecnt+1);
  2136. return(DATA_ERROR);
  2137. }
  2138. lastetime = dummy;
  2139. break;
  2140. case(2):
  2141. if(dummy != 0) {
  2142. sprintf(errstr,"First level (3rd entry) (%lf) in envelope data line (%d) must be zero.\n",dummy,linecnt+1);
  2143. return(DATA_ERROR);
  2144. }
  2145. maxlevel = dummy;
  2146. break;
  2147. case(13):
  2148. if(!flteq(dummy,1.0)) {
  2149. sprintf(errstr,"Last envelope time (14th entry) (%lf) in envelope data line (%d) must be ONE.\n",dummy,linecnt+1);
  2150. return(DATA_ERROR);
  2151. }
  2152. break;
  2153. case(14):
  2154. if(dummy != 0) {
  2155. sprintf(errstr,"Last level (15th entry) (%lf) in envelope data line (%d) must be zero.\n",dummy,linecnt+1);
  2156. return(DATA_ERROR);
  2157. }
  2158. break;
  2159. default:
  2160. if(dummy < 0.0 || dummy > 1.0) {
  2161. sprintf(errstr,"Values and envelope-times in envelope data must lie between 0 and 1 (see line %d).\n",linecnt+1);
  2162. return(DATA_ERROR);
  2163. }
  2164. if(ODD(cnt)) { // ODD entries, envelope-time
  2165. if(dummy <= lastetime) {
  2166. sprintf(errstr,"Envelope times do not increase at entry %d in line %d.\n",cnt+1,linecnt+1);
  2167. return(DATA_ERROR);
  2168. }
  2169. lastetime = dummy;
  2170. } else
  2171. maxlevel = max(dummy,maxlevel);
  2172. break;
  2173. }
  2174. cnt++;
  2175. }
  2176. if(cnt != 15) {
  2177. sprintf(errstr,"Invalid number of entries (%d) on line %d: should be 15 (1 time plus 7-etime-level pairs\n",cnt,linecnt+1);
  2178. return(DATA_ERROR);
  2179. }
  2180. if(!flteq(maxlevel,1.0)) {
  2181. sprintf(errstr,"Envelope data in line %d does not rise to maximum of 1.0.\n",linecnt+1);
  2182. return(DATA_ERROR);
  2183. }
  2184. linecnt++;
  2185. }
  2186. if(linecnt == 0) {
  2187. sprintf(errstr,"No data found in envelope data file.\n");
  2188. return(DATA_ERROR);
  2189. }
  2190. dz->envcount = linecnt; // Number of different envelopes ....
  2191. dz->all_words = 0;
  2192. if((exit_status = store_filename(str,dz))<0)
  2193. return(exit_status);
  2194. fclose(fp);
  2195. return FINISHED;
  2196. }
  2197. /**************************** READ_THE_SPECIAL_DATA ****************************/
  2198. int read_the_special_data(dataptr dz)
  2199. {
  2200. double *envdata, dummy;
  2201. FILE *fp;
  2202. int cnt;
  2203. char temp[800], *p;
  2204. envdata = dz->parray[dz->envsrcs];
  2205. if((fp = fopen(dz->wordstor[0],"r"))==NULL) {
  2206. sprintf(errstr,"Cannot open file %s to envelope data times.\n",dz->wordstor[0]);
  2207. return(DATA_ERROR);
  2208. }
  2209. cnt = 0;
  2210. while(fgets(temp,200,fp)!=NULL) {
  2211. p = temp;
  2212. while(isspace(*p))
  2213. p++;
  2214. if(*p == ';' || *p == ENDOFSTR) // Allow comments in file
  2215. continue;
  2216. while(get_float_from_within_string(&p,&dummy)) {
  2217. envdata[cnt] = dummy;
  2218. cnt++;
  2219. }
  2220. }
  2221. return FINISHED;
  2222. }
  2223. /**************************** FRAGMENT_PARAM_PREPROCESS ****************************/
  2224. int fragment_param_preprocess (int *maxpulse,double *maxtrans,int *minfragmax,dataptr dz)
  2225. {
  2226. int exit_status, chans, strmcnt;
  2227. int n, m, eventcnt;
  2228. double d_minpulse, d_maxpulse, d_minfragmax, srate, leftgain, rightgain, val;
  2229. int *lmost, *rmost;
  2230. double *llev, *rlev, *pos;
  2231. if(dz->mode == 0)
  2232. chans = dz->iparam[FRAC_CHANS];
  2233. else
  2234. chans = STEREO;
  2235. strmcnt = dz->iparam[FRAC_STRMS];
  2236. srate = (double)dz->infile->srate;
  2237. if(dz->brksize[FRAC_PCHRND]) {
  2238. for(n=0,m=1;n < dz->brksize[FRAC_PCHRND];n++,m+=2) {
  2239. val = dz->brk[FRAC_PCHRND][m];
  2240. val /= 100.0; // Convert from cents to semitones
  2241. dz->brk[FRAC_PCHRND][m] = val;
  2242. }
  2243. if((exit_status = get_maxvalue_in_brktable(&val,FRAC_PCHRND,dz))<0)
  2244. return PROGRAM_ERROR;
  2245. *maxtrans = pow(2.0,(val/SEMITONES_PER_OCTAVE));
  2246. } else {
  2247. dz->param[FRAC_PCHRND] /= 100.0;
  2248. val = dz->param[FRAC_PCHRND];
  2249. *maxtrans = pow(2.0,(val/SEMITONES_PER_OCTAVE)); // Retain max transposition for calculation of buffer sizes
  2250. }
  2251. if(dz->brksize[FRAC_MIN]) {
  2252. if((exit_status = get_maxvalue_in_brktable(&d_minfragmax,FRAC_MIN,dz))<0)
  2253. return PROGRAM_ERROR;
  2254. } else
  2255. d_minfragmax = dz->param[FRAC_MIN];
  2256. *minfragmax = (int)ceil(d_minfragmax * srate);
  2257. if(dz->brksize[FRAC_PULSE]) {
  2258. if((exit_status = get_minvalue_in_brktable(&d_minpulse,FRAC_PULSE,dz))<0)
  2259. return PROGRAM_ERROR;
  2260. if((exit_status = get_maxvalue_in_brktable(&d_maxpulse,FRAC_PULSE,dz))<0)
  2261. return PROGRAM_ERROR;
  2262. } else {
  2263. d_minpulse = dz->param[FRAC_PULSE];
  2264. d_maxpulse = dz->param[FRAC_PULSE];
  2265. }
  2266. d_maxpulse *= 2.0; // Allow for maximum randomisation extension of pulse-duration = 1/2 pulse dur, but at BOTH ends
  2267. *maxpulse = (int)ceil(d_maxpulse * srate);
  2268. d_minpulse /= 2.0; // Allow for maximum randomisation reduction of pulse-duration
  2269. eventcnt = (int)ceil(dz->duration/d_minpulse) + 16; // SAFETY
  2270. /*
  2271. * DOUBLE ARRAYS: S = number of streams | llev
  2272. * | | | rlev
  2273. * |---------------|---------------|---------------|---------------|---------------| | pos
  2274. * | depth | level | transpos | envreadtime | stacking | | | tempenv
  2275. * | | | | | 5S| | | envdata
  2276. * | | | | | | 5S+1| | stakcentre
  2277. * address 0 S 2S 3S 4S | | 5S+2| | grptimes
  2278. * | | | | | | | | 5S+3| | chan-levels(mode>0 only)
  2279. * | | | | | | | | | 5S+4| | |
  2280. * array | maxevents | maxevents | maxevents | maxevents | maxevents | | | | | 5S+5| |
  2281. * length | | | | | S S S | | | 5S+6| then 11 filter arrays
  2282. * | | | | | | | | 14| | | | |
  2283. * | | | | | | | | | dz->envcount * 15
  2284. * | | | | | | | | | | S | | |
  2285. * | | | | | | | | | | | maxevents
  2286. * | | | | | | | outchans
  2287. */
  2288. if((dz->parray = (double **)malloc(((strmcnt * 5) + 19) * sizeof(double *)))==NULL) {
  2289. sprintf(errstr,"INSUFFICIENT MEMORY for double arrays.\n");
  2290. return(MEMORY_ERROR);
  2291. }
  2292. for(n=0,m=1;n<strmcnt;n++,m++) { // Envelope depth/stack of each-event-in-each-stream
  2293. if((dz->parray[n] = (double *)malloc(eventcnt * sizeof(double)))==NULL) {
  2294. sprintf(errstr,"INSUFFICIENT MEMORY for stream %d depth array.\n",m);
  2295. return(MEMORY_ERROR);
  2296. }
  2297. }
  2298. for(m=1;n<strmcnt*2;n++,m++) { // Level of each-event-in-each-stream
  2299. if((dz->parray[n] = (double *)malloc(eventcnt * sizeof(double)))==NULL) {
  2300. sprintf(errstr,"INSUFFICIENT MEMORY for stream %d level array.\n",m);
  2301. return(MEMORY_ERROR);
  2302. }
  2303. }
  2304. for(m=1;n<strmcnt*3;n++,m++) { // Transpos for each-event-in-each-stream
  2305. if((dz->parray[n] = (double *)malloc(eventcnt * sizeof(double)))==NULL) {
  2306. sprintf(errstr,"INSUFFICIENT MEMORY for stream %d transposition array.\n",m);
  2307. return(MEMORY_ERROR);
  2308. }
  2309. }
  2310. for(m=1;n<strmcnt*4;n++,m++) { // Times in envtable where envdata read, for each-event-in-each-stream
  2311. if((dz->parray[n] = (double *)malloc(eventcnt * sizeof(double)))==NULL) { // NB these could have been randomised
  2312. sprintf(errstr,"INSUFFICIENT MEMORY for stream %d envelope readtime array.\n",m);
  2313. return(MEMORY_ERROR);
  2314. }
  2315. }
  2316. for(m=1;n<strmcnt*5;n++,m++) { // Stacking values for each-event-in-each-stream
  2317. if((dz->parray[n] = (double *)malloc(eventcnt * sizeof(double)))==NULL) { // NB these could have been randomised
  2318. sprintf(errstr,"INSUFFICIENT MEMORY for stream %d envelope readtime array.\n",m);
  2319. return(MEMORY_ERROR);
  2320. }
  2321. }
  2322. if((dz->parray[n++] = (double *)malloc(strmcnt * sizeof(double)))==NULL) { // Stream level at leftmost channel
  2323. sprintf(errstr,"INSUFFICIENT MEMORY for left-levels array.\n");
  2324. return(MEMORY_ERROR);
  2325. }
  2326. if((dz->parray[n++] = (double *)malloc(strmcnt * sizeof(double)))==NULL) { // Stream level at rightmost channel
  2327. sprintf(errstr,"INSUFFICIENT MEMORY for right-levels array.\n");
  2328. return(MEMORY_ERROR);
  2329. }
  2330. if((dz->parray[n++] = (double *)malloc(strmcnt * sizeof(double)))==NULL) { // Positioning of output streams
  2331. sprintf(errstr,"INSUFFICIENT MEMORY for storing input envelope data.\n");
  2332. return(MEMORY_ERROR);
  2333. }
  2334. dz->envbuf = n; // Store array number of temporary envelope
  2335. if((dz->parray[n++] = (double *)malloc(14 * sizeof(double)))==NULL) { // Stores temporary envelope calculated for specific event
  2336. sprintf(errstr,"INSUFFICIENT MEMORY for current envelope array.\n");
  2337. return(MEMORY_ERROR);
  2338. }
  2339. dz->envsrcs = n; // Store array number of input envelope data
  2340. if((dz->parray[n++] = (double *)malloc((dz->envcount * 15) * sizeof(double)))==NULL) { // Original envelope data in blocks of time+14 = 15
  2341. sprintf(errstr,"INSUFFICIENT MEMORY for storing input envelope data.\n");
  2342. return(MEMORY_ERROR);
  2343. }
  2344. if((dz->parray[n++] = (double *)malloc(strmcnt * sizeof(double)))==NULL) { // Centre of envelope (for stacking)
  2345. sprintf(errstr,"INSUFFICIENT MEMORY for storing input envelope data.\n");
  2346. return(MEMORY_ERROR);
  2347. }
  2348. if((dz->parray[n++] = (double *)malloc(eventcnt * sizeof(double)))==NULL) { // Group-time of events
  2349. sprintf(errstr,"INSUFFICIENT MEMORY for storing input envelope data.\n");
  2350. return(MEMORY_ERROR);
  2351. }
  2352. if(dz->mode > 0) { // Channel levels in calculation of multichannel output
  2353. dz->outlevs = n;
  2354. if((dz->parray[n] = (double *)malloc(dz->iparam[FRAC_CHANS] * sizeof(double)))==NULL) {
  2355. sprintf(errstr,"INSUFFICIENT MEMORY to store out-levels for multichannel output.\n");
  2356. return(MEMORY_ERROR);
  2357. }
  2358. }
  2359. /*
  2360. * INTEGER ARRAYS: S = number of streams
  2361. *
  2362. * lmost
  2363. * | rmost
  2364. * | | |
  2365. * address 0 1 |
  2366. * | | |
  2367. * array S S |
  2368. * length | | |
  2369. */
  2370. if((dz->iparray = (int **)malloc(2 * sizeof(int *)))==NULL) {
  2371. sprintf(errstr,"INSUFFICIENT MEMORY for integer arrays.\n");
  2372. return(MEMORY_ERROR);
  2373. }
  2374. if((dz->iparray[0] = (int *)malloc(strmcnt * sizeof(int)))==NULL) { // leftmost channel for each stream
  2375. sprintf(errstr,"INSUFFICIENT MEMORY for stream leftmost channels.\n");
  2376. return(MEMORY_ERROR);
  2377. }
  2378. if((dz->iparray[1] = (int *)malloc(strmcnt * sizeof(int)))==NULL) { // rightmost channel for each stream
  2379. sprintf(errstr,"INSUFFICIENT MEMORY for stream rightmost channels.\n");
  2380. return(MEMORY_ERROR);
  2381. }
  2382. /*
  2383. * LONG ARRAYS: S = number of streams iptr (start of read WITHIN current input buffer, for each stream)
  2384. * | temp storage of event starttimes
  2385. * |---------------|---------------| | |
  2386. * | segendsamp | inreadsamp | | | NB segendsamp is in MONO samps
  2387. * address 0 S 2S| | need to change to (segendsamp * chans)
  2388. * | | | 2S+1 + lmost(rmost) % dz->buflen
  2389. * array | maxevents | maxevents | | | for write!!
  2390. * length | | strmcnt
  2391. * | | | strmcnt
  2392. */
  2393. if((dz->lparray = (int **)malloc(((strmcnt*2)+2) * sizeof(int *)))==NULL) {
  2394. sprintf(errstr,"INSUFFICIENT MEMORY for ints arrays.\n");
  2395. return(MEMORY_ERROR);
  2396. }
  2397. for(n=0,m=1;n<strmcnt;n++,m++) { // End sample for each-event-in-each-stream, counted in MONO
  2398. if((dz->lparray[n] = (int *)malloc(eventcnt * sizeof(int)))==NULL) {
  2399. sprintf(errstr,"INSUFFICIENT MEMORY for stream %d eventend sampletimes.\n",m);
  2400. return(MEMORY_ERROR);
  2401. }
  2402. }
  2403. for(m=1;n<strmcnt*2;n++,m++) { // Startsample in source for each-event-in-each-stream
  2404. if((dz->lparray[n] = (int *)malloc(eventcnt * sizeof(int)))==NULL) {
  2405. sprintf(errstr,"INSUFFICIENT MEMORY for stream %d eventread sampletimes.\n",m);
  2406. return(MEMORY_ERROR);
  2407. }
  2408. } // Pointers within CURRENT buffer, to start of segments to read, for each stream
  2409. if((dz->lparray[n++] = (int *)malloc(strmcnt * sizeof(int)))==NULL) {
  2410. sprintf(errstr,"INSUFFICIENT MEMORY for stream src Pointers in input buffers.\n");
  2411. return(MEMORY_ERROR);
  2412. } // Temporary storage of event start-times for each stream
  2413. if((dz->lparray[n] = (int *)malloc(strmcnt * sizeof(int)))==NULL) {
  2414. sprintf(errstr,"INSUFFICIENT MEMORY for stream src Pointers in input buffers.\n");
  2415. return(MEMORY_ERROR);
  2416. }
  2417. if((exit_status = read_the_special_data(dz))<0) // Read the envelope data input
  2418. return exit_status;
  2419. // Assign output streams to correct positions among output channels
  2420. lmost = dz->iparray[0];
  2421. rmost = dz->iparray[1];
  2422. llev = dz->parray[strmcnt * 5];
  2423. rlev = dz->parray[(strmcnt * 5) + 1];
  2424. pos = dz->parray[(strmcnt * 5) + 2];
  2425. if(strmcnt == chans) {
  2426. for(n = 0;n<chans;n++) {
  2427. lmost[n] = n;
  2428. rmost[n] = (lmost[n] + 1) % chans;
  2429. llev[n] = 1.0;
  2430. rlev[n] = 0.0;
  2431. }
  2432. } else {
  2433. if((dz->mode == 0 && dz->vflag[1]) || chans == 2) {
  2434. for(n = 0;n<strmcnt;n++) {
  2435. pos[n] = ((chans - 1) * n)/(double)(strmcnt - 1);
  2436. lmost[n] = (int)floor(pos[n]);
  2437. pos[n] -= lmost[n];
  2438. }
  2439. } else {
  2440. for(n = 0;n<strmcnt;n++) {
  2441. pos[n] = (chans * n)/(double)strmcnt;
  2442. lmost[n] = (int)floor(pos[n]);
  2443. pos[n] -= lmost[n];
  2444. }
  2445. }
  2446. for(n = 0;n<strmcnt;n++) {
  2447. rmost[n] = (lmost[n] + 1) % chans;
  2448. if(flteq(pos[n],0.0)) {
  2449. rlev[n] = 0.0;
  2450. llev[n] = 1.0; // pos values overwritten by associated level values (ETC below)
  2451. } else if(flteq(pos[n],1.0)) {
  2452. rlev[n] = 1.0;
  2453. llev[n] = 0.0;
  2454. } else {
  2455. pos[n] *= 2.0;
  2456. pos[n] -= 1.0; // Change position to -1 to +1 range
  2457. pancalc(pos[n],&leftgain,&rightgain);
  2458. rlev[n] = rightgain;
  2459. llev[n] = leftgain;
  2460. }
  2461. }
  2462. }
  2463. if(dz->mode > 0) {
  2464. // SET UP FILTER
  2465. if((exit_status = setup_lphp_filter(dz))<0) // Set up the distance filter
  2466. return exit_status;
  2467. }
  2468. return FINISHED;
  2469. }
  2470. /**************************** CREATE_FRACTURE_SNDBUFS ****************************/
  2471. int create_fracture_sndbufs(int maxpulse,double maxtrans,int minfragmax,int *ibuflen,int *envbuflen,int *overflow, int *mbuflen, dataptr dz)
  2472. {
  2473. int framesize = dz->infile->channels * F_SECSIZE;
  2474. int chans;
  2475. unsigned int bigbufsize;
  2476. int seccnt, obuflen, fbuflen = 0;
  2477. double d_obuflen;
  2478. if(dz->mode == 0)
  2479. chans = dz->iparam[FRAC_CHANS];
  2480. else
  2481. chans = STEREO;
  2482. if((dz->sampbuf = (float **)malloc(sizeof(float *) * 8))==NULL) {
  2483. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffers.\n");
  2484. return(MEMORY_ERROR);
  2485. }
  2486. if((dz->sbufptr = (float **)malloc(sizeof(float *) * 8))==NULL) {
  2487. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffer pointers.\n");
  2488. return(MEMORY_ERROR);
  2489. }
  2490. *ibuflen = maxpulse; // Already allows for maximum random expansion of maximum read-segment length
  2491. *ibuflen *= 3; // Allow for maximum offset of reads in different streams
  2492. *ibuflen += minfragmax; // Allows for minimum fragment-size being larger than maxpulse
  2493. *ibuflen += 64; // SAFETY
  2494. seccnt = *ibuflen/framesize;
  2495. if(seccnt * framesize != *ibuflen) {
  2496. seccnt++;
  2497. *ibuflen = seccnt * framesize;
  2498. }
  2499. *envbuflen = maxpulse * 2; // Frag start and ends can be randomly displaced away from one another ... allow a maximum safety margin!!
  2500. *envbuflen += minfragmax; // If a minimum fragment-size specified, allows for length of minsize + any rand-extension
  2501. *envbuflen += 16; // SAFETY
  2502. seccnt = (*envbuflen)/framesize;
  2503. if(seccnt * framesize != *envbuflen) {
  2504. seccnt++;
  2505. *envbuflen = seccnt * framesize;
  2506. }
  2507. d_obuflen = (double)maxpulse;
  2508. if(maxtrans > 1.0) // Allow for maximum transposition (downwards) of data (redundant: transpos always upwards)
  2509. d_obuflen *= maxtrans;
  2510. obuflen = (int)ceil(d_obuflen) + 16; // SAFETY
  2511. obuflen *= chans;
  2512. seccnt = obuflen/framesize;
  2513. if(seccnt * framesize != obuflen) {
  2514. seccnt++;
  2515. obuflen = seccnt * framesize;
  2516. }
  2517. if(dz->mode > 0) {
  2518. *mbuflen = (obuflen/STEREO) * dz->iparam[FRAC_CHANS];
  2519. fbuflen = obuflen;
  2520. }
  2521. *overflow = obuflen * 2; // Allow for 2 whole maximal segments overwrite of end of output buffer
  2522. *overflow += minfragmax; // Allow for min-length segments which are bigger than maxpulse
  2523. dz->buflen = obuflen;
  2524. bigbufsize = *ibuflen + (*envbuflen * 2) + obuflen + *overflow + fbuflen + *mbuflen;
  2525. if((dz->bigbuf = (float *)malloc(bigbufsize * sizeof(float))) == NULL) {
  2526. sprintf(errstr,"INSUFFICIENT MEMORY to create sound buffers.\n");
  2527. return(MEMORY_ERROR);
  2528. }
  2529. /*
  2530. * SOUND BUFFERS
  2531. *
  2532. * MODE 1 | input | enveloping| stacking | output | overflow |
  2533. *
  2534. * MODE 2 | input | enveloping| stacking | stereo | stereo | filter | multichan |
  2535. * output overflow buffer output
  2536. */
  2537. dz->sampbuf[0] = dz->bigbuf;
  2538. dz->sbufptr[0] = dz->sampbuf[0];
  2539. dz->sampbuf[1] = dz->sampbuf[0] + *ibuflen;
  2540. dz->sbufptr[1] = dz->sampbuf[1];
  2541. dz->sampbuf[2] = dz->sampbuf[1] + *envbuflen;
  2542. dz->sbufptr[2] = dz->sampbuf[2];
  2543. dz->sampbuf[3] = dz->sampbuf[2] + *envbuflen;
  2544. dz->sbufptr[3] = dz->sampbuf[3];
  2545. dz->sampbuf[4] = dz->sampbuf[3] + obuflen;
  2546. dz->sbufptr[4] = dz->sampbuf[4];
  2547. dz->sampbuf[5] = dz->sampbuf[4] + *overflow;
  2548. dz->sbufptr[5] = dz->sampbuf[5];
  2549. dz->sampbuf[6] = dz->sampbuf[5] + fbuflen;
  2550. dz->sbufptr[6] = dz->sampbuf[6];
  2551. dz->sampbuf[7] = dz->sampbuf[6] + *mbuflen;
  2552. dz->sbufptr[7] = dz->sampbuf[7];
  2553. return FINISHED;
  2554. }
  2555. /**************************** READ_THE_ENVELOPE ****************************/
  2556. int read_the_envelope(double now, dataptr dz)
  2557. {
  2558. double *envarray = dz->parray[dz->envsrcs], *tempenv = dz->parray[dz->envbuf];
  2559. int n, m, k, thisenv, lastenv, lastj, thisj, endj;
  2560. double time_of_envelope, lasttime, thistime, timediff, timefrac, val;
  2561. for(n = 0,m= 0;m < dz->envcount; n+=15,m++) { // Step through the time values, at every 15th entry
  2562. time_of_envelope = envarray[n];
  2563. if(time_of_envelope >= now) { // Once time-of-envelope is beyond "now" time
  2564. thisenv = m; // Mark the two envelopes bracketing "now"
  2565. lastenv = m-1;
  2566. if(lastenv < 0) { // If there is no previous envelope, we must be at zero time
  2567. for(k=0;k<14;k++) // so copy envelope at zero time to output (temporary envelope)
  2568. tempenv[k] = envarray[k+1];
  2569. return FINISHED;
  2570. } else { // Otherwise, get the array-indexes of the times of the bracketing envelopes
  2571. lastj = lastenv * 15;
  2572. thisj = thisenv * 15;
  2573. endj = thisj; // And remember the index of the END of the last-envelope data
  2574. lasttime = envarray[lastj]; // get those bracketing times
  2575. thistime = envarray[thisj]; // and calculate the fraction of time we are at, between the bracketing times
  2576. timediff = thistime - lasttime;
  2577. timefrac = (now - lasttime)/timediff;
  2578. lastj++; // Step from time-of-envelope to envelope data itself
  2579. thisj++;
  2580. k = 0; // Initialise counter for output temporary-envelope
  2581. while(lastj < endj) { // For every (time and level) entry in the bracketing envelopes
  2582. val = envarray[thisj] - envarray[lastj];
  2583. val *= timefrac; // Interpolate using timefrac
  2584. val += envarray[lastj];
  2585. tempenv[k++] = val;
  2586. lastj++;
  2587. thisj++;
  2588. }
  2589. return FINISHED;
  2590. }
  2591. }
  2592. } // If we've gone through all data without reaching input "time", use final envelope
  2593. lastenv = m-1;
  2594. lastj = lastenv * 15;
  2595. lastj++;
  2596. for(k=0;k<14;k++)
  2597. tempenv[k] = envarray[lastj++];
  2598. return FINISHED;
  2599. }
  2600. /**************************** GETSTAKCENTRE ****************************
  2601. *
  2602. * Find time of (first) peak in envelope
  2603. */
  2604. double getstakcentre(double *tempenv,dataptr dz)
  2605. {
  2606. int tim, lev;
  2607. double maxlev = -1.0;
  2608. double maxtim = 0.0;
  2609. for(tim=0,lev=1;tim < 14;tim+=2,lev+=2) {
  2610. if(tempenv[lev] > maxlev) {
  2611. maxlev = tempenv[lev];
  2612. maxtim = tempenv[tim];
  2613. }
  2614. }
  2615. return maxtim;
  2616. }
  2617. /**************************** GETSTAKWRITESTT ****************************
  2618. *
  2619. * Find sample in stak-buffer where transposed-data, centred on peak, should start to be written
  2620. */
  2621. int getstakwritestt(double stakcntr,int ldur,double incr)
  2622. {
  2623. double stakcentre = (double)ldur * stakcntr;
  2624. double shrinkto = stakcentre/incr;
  2625. return (int)round(stakcentre - shrinkto);
  2626. }
  2627. /************************************ PANCALC *******************************/
  2628. void pancalc(double position,double *leftgain,double *rightgain)
  2629. {
  2630. int dirflag;
  2631. double temp;
  2632. double relpos;
  2633. double reldist, invsquare;
  2634. if(position < 0.0)
  2635. dirflag = SIGNAL_TO_LEFT; /* signal on left */
  2636. else
  2637. dirflag = SIGNAL_TO_RIGHT;
  2638. if(position < 0)
  2639. relpos = -position;
  2640. else
  2641. relpos = position;
  2642. if(relpos <= 1.0){ /* between the speakers */
  2643. temp = 1.0 + (relpos * relpos);
  2644. reldist = ROOT2 / sqrt(temp);
  2645. temp = (position + 1.0) / 2.0;
  2646. *rightgain = temp * reldist;
  2647. *leftgain = (1.0 - temp ) * reldist;
  2648. } else { /* outside the speakers */
  2649. temp = (relpos * relpos) + 1.0;
  2650. reldist = sqrt(temp) / ROOT2; /* relative distance to source */
  2651. invsquare = 1.0 / (reldist * reldist);
  2652. if(dirflag == SIGNAL_TO_LEFT){
  2653. *leftgain = invsquare;
  2654. *rightgain = 0.0;
  2655. } else { /* SIGNAL_TO_RIGHT */
  2656. *rightgain = invsquare;
  2657. *leftgain = 0;
  2658. }
  2659. }
  2660. }
  2661. /*************************** PANSPREAD ****************************
  2662. *
  2663. * This function takes the output of mode 0 (but forced to stereo)
  2664. * and uses it as the stereo input to the multichannel spatialiseation process (of "mchanpan" - MODE 3- stereo input branch)
  2665. *
  2666. * Data is fed in in chunks of dz->buflen (or possibly less for the last chunk)
  2667. * and written to multichannel output from here.
  2668. *
  2669. * There is no reason to run this part of the function during the level-testing pass
  2670. * as, once the stereo level has been normalised, there is no (per channel) level increase at this stage.
  2671. *
  2672. * Signal gain has several componenets
  2673. * Stereo positioning gain (relative level on Left/Right loudspeakers) is already included in the input stereo signal
  2674. * Position gain perpendicular to stereo-plain OR attenuation with distance beyond the circle
  2675. * Natural attenuation of the image "atten" where it fades before reaching infinity.
  2676. * Externally imposed gain-reduction "gain" to avoid an overload.
  2677. */
  2678. int panspread(int *sectcnt,double *centre,double *spread,int *cntrswitch,int *outside,double *fmix,int samps_to_process,dataptr dz)
  2679. {
  2680. int exit_status, pan_exit_status = CONTINUE, outchans = dz->iparam[FRAC_CHANS], m, k;
  2681. int ibufpos, obufpos = 0;
  2682. double *levels;
  2683. int inchans = STEREO;
  2684. float *ibuf = dz->sampbuf[3]; // Input buffer is the former "obuf", now used as intermediate stereo-storage
  2685. float *fbuf = dz->sampbuf[5]; // buffer for filtering
  2686. float *obuf = dz->sampbuf[6]; // and the output buffer is the multichan-outbuf "mbuf"
  2687. double time = 0.0, srate = (double)dz->infile->srate, gain = dz->param[FRAC_GAIN];
  2688. int obuflen = (dz->buflen/STEREO) * outchans;
  2689. double stereo_pos, atten, timeratio;
  2690. double relpos, temp, holecompensate;
  2691. double left_leftchan_level, left_ritechan_level;
  2692. double valcentre, valoffcen;
  2693. double fadeoutat = dz->fulldur - dz->param[FRAC_DN];
  2694. int halfstage = outchans/2;
  2695. int c_left, c_rite, cen_tr;
  2696. double left_contrib_to_c_left, rite_contrib_to_c_left, left_contrib_to_c_rite, rite_contrib_to_c_rite, val;
  2697. levels = dz->parray[dz->outlevs]; // Array created earlier.
  2698. memset((char *)obuf,0,obuflen * sizeof(float));
  2699. if(dz->param[FRAC_DN] <= 0.0)
  2700. fadeoutat = dz->fulldur * 200.0; // i.e. an unreachable time
  2701. for(ibufpos = 0, obufpos = 0;ibufpos < samps_to_process;ibufpos+=inchans,obufpos += outchans) {
  2702. if((*sectcnt) % 256 == 0) {
  2703. time = (double)(*sectcnt)/srate;
  2704. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  2705. return(exit_status);
  2706. if(spread_pan(centre,cntrswitch,outside,spread,fmix,dz) == FINISHED) {
  2707. pan_exit_status = FINISHED;
  2708. break;
  2709. }
  2710. }
  2711. if(time < dz->param[FRAC_UP]) { // Factor in any natural decay of event (i.e NOT distance realted)
  2712. timeratio = time/dz->param[FRAC_UP];
  2713. atten = pow(timeratio,dz->param[FRAC_ATTEN]);
  2714. } else if(time > fadeoutat) {
  2715. timeratio = (time - fadeoutat)/dz->param[FRAC_DN];
  2716. timeratio = 1.0 - timeratio;
  2717. atten = pow(timeratio,dz->param[FRAC_ATTEN]);
  2718. } else
  2719. atten = 1.0;
  2720. atten *= gain; // Factor in any externally imposed gain-limiting.
  2721. if(*outside) {
  2722. stereo_pos = 1.0 - *spread; // Spread is to left of centre, incresing leftward, but stereo-position measured rightward
  2723. relpos = fabs(0.5 - stereo_pos) * 2.0; // position relative_to_stereo_centre : Range 0-1 goes to 1-0-1
  2724. temp = 1.0 + (relpos * relpos); // calculate stereo-hole-in-middle compensation
  2725. holecompensate = ROOT2 / sqrt(temp);
  2726. left_leftchan_level = *spread * levels[0] * holecompensate; // contrib of left chan to left edge of shrunk image
  2727. left_ritechan_level = (1-(*spread)) * levels[0] * holecompensate; // contrib of right chan to left edge of shrunk image
  2728. // ADD IN ANY FILTERED SOUND, TO STEREO IMAGE
  2729. if(*fmix > 0) {
  2730. ibuf[ibufpos] = (float)(((1-(*fmix)) * ibuf[ibufpos]) + (*fmix * fbuf[ibufpos]));
  2731. ibuf[ibufpos+1] = (float)(((1-(*fmix)) * ibuf[ibufpos+1]) + (*fmix * fbuf[ibufpos+1]));
  2732. }
  2733. if(*cntrswitch == 0) {
  2734. valcentre = ibuf[ibufpos+1]; // The RHS of stereo will remain where it is
  2735. valoffcen = ibuf[ibufpos]; // The LHS will drift towards the right, till they become mono, at right (=final image centre)
  2736. } else {
  2737. valcentre = ibuf[ibufpos]; // LHS & RHS of original stereo signal switched, because centre moved to opposite pole: see elsewhere
  2738. valoffcen = ibuf[ibufpos+1];
  2739. }
  2740. valcentre = valcentre + (left_ritechan_level * valoffcen); // Stereo-right + an increasing portion of stereo-left
  2741. valoffcen = left_leftchan_level * valoffcen; // a decreasing portion of stereo left
  2742. cen_tr = (int)floor(*centre);
  2743. c_left = cen_tr - 1;
  2744. if(c_left < 0)
  2745. c_left += outchans;
  2746. obuf[obufpos + cen_tr] = (float)(valcentre * atten * levels[0]); // Attenuation is any dying away of signal proper (nothing to do with distance)
  2747. obuf[obufpos + c_left] = (float)(valoffcen * atten * levels[0]); // levels[0] is the level associated with distance from circle
  2748. } else {
  2749. c_left = (int)floor(*centre);
  2750. c_rite = c_left + 1;
  2751. if(c_rite >= outchans)
  2752. c_rite -= outchans;
  2753. for(k=1;k<halfstage;k++) { // All loudpseakers to left of central pair get left signal (unless reading from opp. centre : cntrswitch = 1)
  2754. m = c_left - k; // Values in "levels" decide how much of the signal is played
  2755. if(m < 0)
  2756. m += outchans;
  2757. if(*cntrswitch)
  2758. obuf[obufpos + m] = (float)(ibuf[ibufpos+1] * levels[m] * atten);
  2759. else
  2760. obuf[obufpos + m] = (float)(ibuf[ibufpos] * levels[m] * atten);
  2761. }
  2762. for(k=1;k<halfstage;k++) { // All loudpseakers to right of central pair get right signal (unless etc.)
  2763. m = c_rite + k;
  2764. if(m >= outchans)
  2765. m -= outchans;
  2766. if(*cntrswitch)
  2767. obuf[obufpos + m] = (float)(ibuf[ibufpos] * levels[m] * atten);
  2768. else
  2769. obuf[obufpos + m] = (float)(ibuf[ibufpos+1] * levels[m] * atten);
  2770. } // Central pair get a mix of left and right signals
  2771. stereo_pos = *centre - (double)c_left;
  2772. left_contrib_to_c_left = (1.0 + (2.0 * stereo_pos))/2.0;
  2773. left_contrib_to_c_left = min(1.0,left_contrib_to_c_left);
  2774. rite_contrib_to_c_left = (1.0 - (2.0 * stereo_pos))/2.0;
  2775. rite_contrib_to_c_left = max(0.0,rite_contrib_to_c_left);
  2776. if(*cntrswitch)
  2777. val = (ibuf[ibufpos+1] * left_contrib_to_c_left) + (ibuf[ibufpos] * rite_contrib_to_c_left);
  2778. else
  2779. val = (ibuf[ibufpos] * left_contrib_to_c_left) + (ibuf[ibufpos+1] * rite_contrib_to_c_left);
  2780. val *= levels[c_left];
  2781. obuf[obufpos + c_left] = (float)(val * atten);
  2782. left_contrib_to_c_rite = ((2.0 * stereo_pos) - 1.0)/2.0;
  2783. left_contrib_to_c_rite = max(0.0,left_contrib_to_c_rite);
  2784. rite_contrib_to_c_rite = (3.0 - (2.0 * stereo_pos))/2.0;
  2785. rite_contrib_to_c_rite = min(1.0,rite_contrib_to_c_rite);
  2786. if(*cntrswitch)
  2787. val = (ibuf[ibufpos+1] * left_contrib_to_c_rite) + (ibuf[ibufpos] * rite_contrib_to_c_rite);
  2788. else
  2789. val = (ibuf[ibufpos] * left_contrib_to_c_rite) + (ibuf[ibufpos+1] * rite_contrib_to_c_rite);
  2790. val *= levels[c_rite];
  2791. obuf[obufpos + c_rite] = (float)(val * atten);
  2792. left_contrib_to_c_rite = ((2.0 * stereo_pos) - 1.0)/2.0;
  2793. }
  2794. (*sectcnt)++;
  2795. }
  2796. if(obufpos > 0) {
  2797. if((exit_status = write_samps(obuf,obufpos,dz))<0)
  2798. return(exit_status);
  2799. }
  2800. return pan_exit_status;
  2801. }
  2802. /* WITH CENTRE BETWEEN CHANNELS ...
  2803. * left_contrib_to_c_left = * rite_contrib_to_c_left = * left_contrib_to_c_rite = * rite_contrib_to_c_rite =
  2804. * MAX of 1.0 AND * MIN of 0.0 AND * MAX of 0.0 AND * MAX of 1.0 AND
  2805. * (1.0 + (2.0 * stereo_pos)/2.0; * (1.0 - (2.0 * stereo_pos)/2.0; * ((2.0 * stereo_pos) - 1.0)/2.0; * (3.0 - (2.0 * stereo_pos)/2.0;
  2806. * * * *
  2807. * POSITION OF CENTRE * POSITION OF CENTRE * POSITION OF CENTRE * POSITION OF CENTRE
  2808. * c-left c_rite * c-left c_rite * c-left c_rite * c-left c_rite
  2809. * 1.0 | . . . .________| * 1.0 |. . . . . . . . | * 1.0 | . . . . . . . .| * 1.0 |________ . . . |
  2810. * | / | * | | * | | * | \ |
  2811. * | / | * | | * | | * | \ |
  2812. * | / | * | | * | | * | \ |
  2813. * 0.5 |/ . . . . . . . | * 0.5 |. . . . . . . . | * 0.5 |. . . . . . . . | * 0.5 |. . . . . . . .\|
  2814. * | | * |\ | * | /| * | |
  2815. * | | * | \ | * | / | * | |
  2816. * | | * | \ | * | / | * | |
  2817. * 0.0 | . . . . . . . | * 0.0 | . . \_________| * 0.0 |_________/ . . | * 0.0 | . . . . . . . .|
  2818. *
  2819. */
  2820. /*************************** SPREAD_PAN ****************************/
  2821. int spread_pan(double *thiscentre,int *cntrswitch,int *outside,double *spread,double *fmix,dataptr dz)
  2822. {
  2823. int outchans = dz->iparam[FRAC_CHANS];
  2824. double centre = (double)dz->iparam[FRAC_CENTRE];
  2825. double halfspread = 0.0, front = dz->param[FRAC_FRONT], ffront;
  2826. double depth;
  2827. double rolloff = dz->param[FRAC_ROLLOFF];
  2828. double *levels = dz->parray[dz->outlevs];
  2829. double spredej_left, spredej_right;
  2830. int spredej_left_leftchan, spredej_left_rightchan, spredej_right_leftchan, spredej_right_rightchan, k, j, ochan;
  2831. double range, maxlevel, hole, stereopos_left, stereopos_right, relpos, temp, holecompensate;
  2832. double holej_right, holej_left, zleft, zright, floor_zleft, floor_zright;
  2833. double left_leftchan_level, right_rightchan_level;
  2834. double kk, jj, holing, mingap;
  2835. double contraction_distance, filter_distance;
  2836. *cntrswitch = 0;
  2837. *outside = 0;
  2838. depth = (dz->param[FRAC_MDEPTH] * outchans)/2.0; // Find (max) no of outchans to turn on
  2839. depth = min(depth,(double)outchans/2.0); // depth (no of ON lspks) to each side of centre is 1/2 of this
  2840. if((centre = centre - 1.0) < 0.0) // Change from 1-to-N to 0-to-(N-1) frame, for calculations
  2841. centre += (double)outchans;
  2842. if(fabs(front) <= 1.0) { // If WITHIN the circle of lspkrs
  2843. centre -= 0.5; // force the active centre to be BETWEEN 2 channels
  2844. if(centre < 0.0)
  2845. centre += outchans;
  2846. if(front >= 0) // Front moves from a spread of 1 lspkr-width (at 1)
  2847. *spread = (1-front) * (outchans/2 - 1) + 1; // to a spread of 1/2-of-lspkrs (outchans/2) at midline
  2848. else {
  2849. front = -front; // After midline, hole in lspkrs has same relation to (abs value of) front.
  2850. *spread = (1-front) * (outchans/2 - 1) + 1; // so calculate symmetrically
  2851. *spread = outchans - *spread; // then subtract hole from total lspkrs
  2852. }
  2853. } else { // Leading-edge of front is outside circle of lspkrs
  2854. *outside = 1;
  2855. if(front < -1) { // If passed OUT of ring, place front at its TRAILING edge, for calculations
  2856. front += (dz->param[FRAC_MDEPTH] * 2);
  2857. if(front <= -2) // Once trailing edge of data reaches infinity, curtail output
  2858. return FINISHED;
  2859. else if(front >= -1) { // If trailing edge of front has (unlike true front) NOT left circle of lspkrs
  2860. centre -= 0.5; // force the active centre to be BETWEEN 2 channels
  2861. if(centre < 0.0)
  2862. centre += outchans;
  2863. *outside = 0; // Do normal inside-circle calculations BUT
  2864. centre -= (double)(outchans/2); // Invert frame of reference
  2865. if(centre < 0.0) // centre -> leaving-centre opposite original centre
  2866. centre += (double)outchans;
  2867. front = -front; // Front inverted symmetrically about centre-line (0)
  2868. *cntrswitch = 1; // and left and right inverted in calling loop
  2869. if(front >= 0) // Then calculate spread in normal way, but from this leaving-centre
  2870. *spread = (1-front) * (outchans/2 - 1) + 1;
  2871. else {
  2872. front = -front;
  2873. *spread = (1-front) * (outchans/2 - 1) + 1;
  2874. *spread = outchans - *spread;
  2875. } // As depth MUST now be covering all chans from trailing edge (new "front") to leaving-centre
  2876. depth = (*spread)/2.0; // set depth to real halfspread,
  2877. }
  2878. }
  2879. if(*outside) { // Once front OUTSIDE circle, shrink to MONO into the original-specified central channel
  2880. ffront = fabs(front); // Calculations for outside ring are symmetrical (Range 1 to 2)
  2881. ffront -= 1.0; // Change range to 0-1 : ringedge-to-infinity (Range 0 to 1)
  2882. maxlevel = pow((1.0 - ffront),dz->param[FRAC_ATTEN]); // As front increases, loudness decreases
  2883. // (and only 1channel active, so no scaling required for no. of chans
  2884. contraction_distance = min(1.0,ffront/dz->param[FRAC_ZPOINT]); // Fraction of distance towards zero-angle point, max 1.0
  2885. *spread = pow((1.0 - contraction_distance),dz->param[FRAC_CONTRACT]);// As contraction_distance increases, width decreases
  2886. halfspread = (*spread)/2.0;
  2887. filter_distance = min(1.0,ffront/dz->param[FRAC_FPOINT]); // Fraction of distance towards total-filering point, max 1.0
  2888. *fmix = pow(filter_distance,dz->param[FRAC_FFACTOR]); // As filter_distance increases, proportion filtered sig in mix increases
  2889. centre = (double)dz->iparam[FRAC_CENTRE]; // Revert to original channel-centred centre
  2890. if((centre = centre - 1.0) < 0.0) // Change from 1-to-N to 0-to-(N-1) frame, for calculations
  2891. centre += outchans;
  2892. if(front < 0.0) { // If LEAVING circle,
  2893. *cntrswitch = 1; // Invert left and right in calling loop
  2894. centre += outchans/2; // Invert centre, to opposite-to-centre channel
  2895. if(centre > outchans)
  2896. centre -= outchans;
  2897. }
  2898. for(ochan = 0;ochan < outchans;ochan++)
  2899. levels[ochan] = 0.0;
  2900. levels[0] = maxlevel; // Central channel to which we'll shrink gets current maxlevel, but we canstore it in levels[0]
  2901. *thiscentre = centre;
  2902. return(CONTINUE); // we're returning an "outside" flag, a moved centre, a shrunk "halfspread" and a filtering-mix value
  2903. }
  2904. }
  2905. halfspread = (*spread)/2.0;
  2906. if(depth <= 0.0)
  2907. depth = FLTERR;
  2908. if((halfspread = (*spread)/2.0) == 0.0)
  2909. halfspread = FLTERR;
  2910. for(ochan = 0;ochan < outchans;ochan++)
  2911. levels[ochan] = 0.0;
  2912. /* Establish maxlevel (determined by rolloff) */
  2913. if(*spread < 1.0)
  2914. range = 0.0;
  2915. else
  2916. range = 1.0 - (1.0/(*spread));
  2917. maxlevel = 1.0 - (rolloff * range);
  2918. // Set all channels fully within the spread to maxlevel
  2919. spredej_left = centre - halfspread; // spredej_left and right could be determined
  2920. while(spredej_left < 0) // by a "position-of-front" parameter
  2921. spredej_left += (double)outchans; // working backwards towards centre, using halfspread
  2922. spredej_right = centre + halfspread;
  2923. while(spredej_right >= outchans) // Once this is done .. easier to deal with
  2924. spredej_right -= (double)outchans; // distant (filtered) signalwith no (or limited) width
  2925. spredej_left_leftchan = (int)floor(spredej_left); // at trailing, or leading centre
  2926. if((spredej_left_rightchan = spredej_left_leftchan + 1) >= outchans)
  2927. spredej_left_rightchan = 0; // Centre is behind front if front moving away from entre
  2928. spredej_right_leftchan = (int)floor(spredej_right); // and <= hlafway to f/b midoint.
  2929. // Having crossed that, centre moves to OPPOSITE position.
  2930. hole = *spread - (depth * 2.0); // Once available lspk-spread is < specified spread,
  2931. // there.s no hole in the middle.
  2932. if(*spread >= outchans) { // Once available loudspeaker spread < 2
  2933. for(k = 0;k<outchans; k++) // spread determined articially by how we deal with
  2934. levels[k] = maxlevel; // distance (beyond octagon) effect, and how we filter
  2935. if(hole <= 0.0) // as we shrink the stereo width.
  2936. return CONTINUE;
  2937. } else if(*spread > 1.0) {
  2938. k = spredej_left_leftchan;
  2939. if(spredej_left_leftchan == spredej_left)
  2940. levels[k] = maxlevel;
  2941. if(++k >= outchans)
  2942. k -= outchans;
  2943. while(k != spredej_right_leftchan) {
  2944. levels[k] = maxlevel;
  2945. if(++k >= outchans)
  2946. k -= outchans;
  2947. }
  2948. levels[spredej_right_leftchan] = maxlevel;
  2949. } else { // In fact, this is what is happening here !!!!
  2950. /* Deal with case where spread extends to both sides of a channel, even if less than 1.0 */
  2951. zleft = centre - halfspread;
  2952. zright = centre + halfspread;
  2953. if(zleft < 0.0) {
  2954. zleft += outchans;
  2955. zright += outchans;
  2956. }
  2957. if(zleft >= 0.0)
  2958. floor_zleft = floor(zleft);
  2959. else
  2960. floor_zleft = -ceil(fabs(zleft));
  2961. if(zright >= 0.0)
  2962. floor_zright = floor(zright);
  2963. else
  2964. floor_zright = -ceil(fabs(zright));
  2965. if(floor_zleft < floor_zright)
  2966. levels[spredej_right_leftchan] = maxlevel;
  2967. }
  2968. /* Do fractional channels on leading edges of spread */
  2969. stereopos_left = spredej_left - (double)spredej_left_leftchan;
  2970. relpos = fabs(0.5 - stereopos_left) * 2.0; // position relative_to_stereo_centre : Range 0 - 1
  2971. temp = 1.0 + (relpos * relpos); // calculate stereo-hole-in-middle compensation
  2972. holecompensate = ROOT2 / sqrt(temp);
  2973. left_leftchan_level = (1 - stereopos_left) * maxlevel * holecompensate;
  2974. if(spredej_left_leftchan != spredej_right_leftchan)
  2975. levels[spredej_left_leftchan] = left_leftchan_level;
  2976. stereopos_right = spredej_right - (double)spredej_right_leftchan;
  2977. relpos = fabs(0.5 - stereopos_right) * 2.0; // position relative_to_stereo_centre : Range 0 - 1
  2978. temp = 1.0 + (relpos * relpos); // calculate stereo-hole-in-middle compensation
  2979. holecompensate = ROOT2 / sqrt(temp);
  2980. right_rightchan_level = stereopos_right * maxlevel * holecompensate;
  2981. if(spredej_right > spredej_right_leftchan) {
  2982. if((spredej_right_rightchan = spredej_right_leftchan + 1) >= outchans)
  2983. spredej_right_rightchan -= outchans;
  2984. if(spredej_right_rightchan != spredej_left_rightchan) {
  2985. if(spredej_right_rightchan == spredej_left_leftchan) {
  2986. levels[spredej_right_rightchan] += right_rightchan_level;
  2987. } else {
  2988. levels[spredej_right_rightchan] = right_rightchan_level;
  2989. }
  2990. }
  2991. }
  2992. /* IF hole in the middle of the spread, because depth too small, find edges of hole */
  2993. halfspread = (*spread)/2.0;
  2994. if(hole > 0.0) {
  2995. holej_right = centre + halfspread - depth;
  2996. holej_left = centre - halfspread + depth;
  2997. k = (int)ceil(holej_left);
  2998. j = (int)floor(holej_right); // Look at all chans in hole
  2999. while(k <= j) {
  3000. kk = k - holej_left;
  3001. jj = holej_right - k;
  3002. mingap = min(jj,kk);
  3003. holing = min(mingap,1.0);
  3004. holing = 1.0 - holing;
  3005. ochan = k;
  3006. while(ochan < 0)
  3007. ochan += outchans;
  3008. while(ochan >= outchans)
  3009. ochan -= outchans;
  3010. levels[ochan] *= holing;
  3011. k++;
  3012. }
  3013. }
  3014. *thiscentre = centre;
  3015. return CONTINUE;
  3016. }
  3017. /*
  3018. * INNER HOLE
  3019. * range = Starts at 1.0 , where no hole. Ends at appropriate stereo-position-level (this_level), once hole extends as far as an existing chan;
  3020. * mingap = minimum distance from holeedge to nearest channel
  3021. * mingap += hole; we then add this to size of hole, to see size of area including hole and distance to nearest chan. Always <= 1.0;
  3022. * holeratio = hole/mingap; with a tiny hole, this is always c. zero, as hole enlarges, gets bigger, till, when hole touches a channel, it gets to be 1.0
  3023. * this_level = 1.0 - (range * holeratio); When holeratio = 1, level becomes 1.0 - range = this_level i.e. expected stereo level
  3024. * = 1.0 - (1.0 - this_level) = this_level i.e. expected stereo level
  3025. */
  3026. /*
  3027. * POSITIONS OF MOVING FRONT
  3028. * 2 = "+infinitely" distant: 1 = in plane of front-centre lspkr : 0 = in plane of midline:
  3029. * -1 = in plane of read lspkr: -2 = "-infinitely" distant
  3030. *
  3031. * Depth-param now expressed as fraction of lspkr-space. 1 = chans, 1/2 = chans/2 etc ..... (so original spread param = depth *chans)
  3032. *
  3033. * 2 Let "spread" at 1 be 1/chans (i.e. 1/2 lspkr width on either side of central lspkr)
  3034. * "spread" at centre (front = 0) is always ochans/2
  3035. * 1 For "front" in range 1 - 0 therefore.
  3036. * x x spread = ((1 - front) * (chans/2 - 1)) + 1 and calculations can proceed as normal
  3037. * For front in range 0 to -1,by symmetry
  3038. * x 0 x spread = chans - (((1 + front) * (chans/2 - 1)) + 1)
  3039. *
  3040. * x x As the front has a depth, and therefore a trailing edge which does not reach -1 at same time as true front,
  3041. * -1 calculations relating to fade-out and filtering between -1 and -2, have to be based on trailing edge vals.
  3042. * So trailing edge only reaches -2 when front is at -2+depth.
  3043. * User needs to build this in to the "fonr" breakpoint file data.
  3044. * -2
  3045. * With the new value of depth, trailing edge is at front + (depth * 2)
  3046. * This is "+" as front always move +ve to -ve
  3047. * and uses factor "2" because, when depth 1 = all lspkrs in use, but distance front to back (1 to -1) = 2.
  3048. * So if 1/2 loudpseakers are activated, trailing edge is half-way back round space and:
  3049. * and "HALFway" for front means distance of "1" (Thus depth[1/2] * 2 = 1)
  3050. */
  3051. //FILTER
  3052. // set stopfrq [expr $sd(filt) + (double($sd(filt))/4.0)]
  3053. // set cmd [file join $evv(CDPROGRAM_DIR) filter]
  3054. // set cmd [list $cmd lohi 1 $sd_infnam cdptest0$evv(SNDFILE_EXT) -96 $sd(filt) $stopfrq]
  3055. /****************************** FILTER_PROCESS *************************/
  3056. int filter_process(int *samps_to_process,int *endzeros,dataptr dz)
  3057. {
  3058. int exit_status;
  3059. float *fbuf = dz->sampbuf[5], *obuf = dz->sampbuf[3];
  3060. int n;
  3061. memset((char *)fbuf,0,dz->buflen * sizeof(float));
  3062. if(*samps_to_process)
  3063. memcpy((char *)fbuf,(char *)obuf,*samps_to_process * sizeof(float));
  3064. dz->ssampsread = dz->buflen; // To force filter to continue to operate, when input exhausted
  3065. if((exit_status = do_lphp_filter_stereo(dz)) <0)
  3066. return(exit_status);
  3067. if( *samps_to_process == 0) {
  3068. n = dz->buflen - 1;
  3069. while(n >= 0) { // Force exit when 256 consecutive grp-samples are zero
  3070. if(fbuf[n] == 0.0)
  3071. (*endzeros)++;
  3072. else
  3073. break;
  3074. n--;
  3075. }
  3076. n++;
  3077. if(*endzeros >= 256 * STEREO) {
  3078. *samps_to_process = n;
  3079. return FINISHED;
  3080. }
  3081. }
  3082. return(CONTINUE);
  3083. }
  3084. /***************************** FILTER *************************************/
  3085. int do_lphp_filter_stereo(dataptr dz)
  3086. {
  3087. int exit_status, i;
  3088. int index, fbase = dz->outlevs + 1;
  3089. double *e1,*e2,*s1,*s2;
  3090. double *den1 = dz->parray[fbase + FLT_DEN1];
  3091. double *den2 = dz->parray[fbase + FLT_DEN2];
  3092. double *cn = dz->parray[fbase + FLT_CN];
  3093. for(i=0; i < STEREO; i++) {
  3094. index = i * FLT_LPHP_ARRAYS_PER_FILTER;
  3095. e1 = dz->parray[fbase + FLT_E1_BASE + index];
  3096. e2 = dz->parray[fbase + FLT_E2_BASE + index];
  3097. s1 = dz->parray[fbase + FLT_S1_BASE + index];
  3098. s2 = dz->parray[fbase + FLT_S2_BASE + index];
  3099. if((exit_status = lphp_filt_stereo(e1,e2,s1,s2,den1,den2,cn,dz,i))<0)
  3100. return exit_status;
  3101. }
  3102. return(FINISHED);
  3103. }
  3104. /***************************** LPHP_FILT_CHAN *************************************/
  3105. int lphp_filt_stereo(double *e1,double *e2,double *s1,double *s2,
  3106. double *den1,double *den2,double *cn,dataptr dz,int chan)
  3107. {
  3108. int i;
  3109. int k;
  3110. float *buf = dz->sampbuf[5];
  3111. double ip, op = 0.0, b1;
  3112. for (i = chan ; i < dz->ssampsread; i+= STEREO) {
  3113. ip = (double) buf[i];
  3114. for (k = 0 ; k < dz->fltcnt; k++) {
  3115. b1 = dz->fltmul * cn[k];
  3116. op = (cn[k] * ip) + (den1[k] * s1[k]) + (den2[k] * s2[k]) + (b1 * e1[k]) + (cn[k] * e2[k]);
  3117. s2[k] = s1[k];
  3118. s1[k] = op;
  3119. e2[k] = e1[k];
  3120. e1[k] = ip;
  3121. }
  3122. if(op >= HUGE || op <= -HUGE) {
  3123. sprintf(errstr,"Filter numeric overflow at %lf secs: try a different (higher) cutoff frequency.\n",
  3124. (double)((dz->total_samps_written/dz->infile->channels) + (i/STEREO))/(double)dz->infile->srate);
  3125. return GOAL_FAILED;
  3126. }
  3127. op *= dz->scalefact;
  3128. if (fabs(op) > 1.0) {
  3129. dz->scalefact *= .9999;
  3130. if (op > 0.0)
  3131. op = 1.0;
  3132. else
  3133. op = -1.0;
  3134. }
  3135. buf[i] = (float)op;
  3136. }
  3137. return FINISHED;
  3138. }
  3139. /********************************* SETUP_LPHP_FILTER *****************************/
  3140. int setup_lphp_filter(dataptr dz)
  3141. {
  3142. int exit_status;
  3143. int filter_order;
  3144. double signd = 1.0, passfrq, stopfrq;
  3145. dz->scalefact = 1.0; // Start with no prescaling: turn down if filter blows up
  3146. passfrq = dz->param[FRAC_FFREQ];
  3147. stopfrq = dz->param[FRAC_FFREQ] * 1.25;
  3148. signd = -1.0;
  3149. dz->fltmul = 2.0;
  3150. filter_order = establish_order_of_filter(passfrq,stopfrq,dz);
  3151. if((exit_status = allocate_internal_params_lphp(dz))<0)
  3152. return(exit_status);
  3153. calculate_filter_poles_lphp(signd,filter_order,passfrq,dz);
  3154. initialise_filter_coeffs_lphp(dz);
  3155. return(FINISHED);
  3156. }
  3157. /********************************* ESTABLISH_ORDER_OF_FILTER *****************************/
  3158. int establish_order_of_filter(double passfrq,double stopfrq,dataptr dz)
  3159. {
  3160. int filter_order;
  3161. double tc, tp, tt, pii, xx, yy, fltgain = FILTER_GAIN;
  3162. double sr = (double)dz->infile->srate;
  3163. pii = 4.0 * atan(1.0);
  3164. passfrq = pii * passfrq/sr;
  3165. tp = tan(passfrq);
  3166. stopfrq = pii * stopfrq/sr;
  3167. tc = tan(stopfrq);
  3168. tt = tc / tp ;
  3169. tt = (tt * tt);
  3170. fltgain = fabs(fltgain);
  3171. fltgain = fltgain * log(10.0)/10.0 ;
  3172. fltgain = exp(fltgain) - 1.0 ;
  3173. xx = log(fltgain)/log(tt) ;
  3174. yy = floor(xx);
  3175. if ((xx - yy) == 0.0 )
  3176. yy = yy - 1.0 ;
  3177. filter_order = ((int)yy) + 1;
  3178. if (filter_order <= 1)
  3179. filter_order = 2;
  3180. dz->fltcnt = filter_order/2 ;
  3181. filter_order = 2 * dz->fltcnt;
  3182. dz->fltcnt = min(dz->fltcnt,200);
  3183. filter_order = 2 * dz->fltcnt;
  3184. return(filter_order);
  3185. }
  3186. /********************************* ALLOCATE_INTERNAL_PARAMS_LPHP *****************************/
  3187. int allocate_internal_params_lphp(dataptr dz)
  3188. {
  3189. int fbase = dz->outlevs + 1;
  3190. int i;
  3191. if((dz->parray[fbase + FLT_DEN1] = (double *)calloc(dz->fltcnt * sizeof(double),sizeof(char)))==NULL
  3192. || (dz->parray[fbase + FLT_DEN2] = (double *)calloc(dz->fltcnt * sizeof(double),sizeof(char)))==NULL
  3193. || (dz->parray[fbase + FLT_CN] = (double *)calloc(dz->fltcnt * sizeof(double),sizeof(char)))==NULL
  3194. || (dz->parray[fbase + FLT_S1_BASE] = (double *)calloc(dz->fltcnt * sizeof(double),sizeof(char)))==NULL
  3195. || (dz->parray[fbase + FLT_E1_BASE] = (double *)calloc(dz->fltcnt * sizeof(double),sizeof(char)))==NULL
  3196. || (dz->parray[fbase + FLT_S2_BASE] = (double *)calloc(dz->fltcnt * sizeof(double),sizeof(char)))==NULL
  3197. || (dz->parray[fbase + FLT_E2_BASE] = (double *)calloc(dz->fltcnt * sizeof(double),sizeof(char)))==NULL) {
  3198. sprintf(errstr,"INSUFFICIENT MEMORY for arrays of filter parameters.\n");
  3199. return(MEMORY_ERROR);
  3200. }
  3201. for(i = 1; i < STEREO;i++) {
  3202. int index = i*FLT_LPHP_ARRAYS_PER_FILTER;
  3203. if((dz->parray[fbase + FLT_S1_BASE + index] = (double *)calloc(dz->fltcnt * sizeof(double),sizeof(char)))==NULL
  3204. || (dz->parray[fbase + FLT_E1_BASE + index] = (double *)calloc(dz->fltcnt * sizeof(double),sizeof(char)))==NULL
  3205. || (dz->parray[fbase + FLT_S2_BASE + index] = (double *)calloc(dz->fltcnt * sizeof(double),sizeof(char)))==NULL
  3206. || (dz->parray[fbase + FLT_E2_BASE + index] = (double *)calloc(dz->fltcnt * sizeof(double),sizeof(char)))==NULL) {
  3207. sprintf(errstr,"INSUFFICIENT MEMORY for arrays of filter parameters.\n");
  3208. return(MEMORY_ERROR);
  3209. }
  3210. }
  3211. return(FINISHED);
  3212. }
  3213. /********************************* CALCULATE_FILTER_POLES_LPHP *****************************/
  3214. void calculate_filter_poles_lphp(double signd,int filter_order,double passfrq,dataptr dz)
  3215. {
  3216. double ss, xx, aa, tppwr, x1, x2, cc;
  3217. double pii = 4.0 * atan(1.0);
  3218. double tp = tan(passfrq);
  3219. int k;
  3220. int fbase = dz->outlevs + 1;
  3221. ss = pii / (double)(2 * filter_order);
  3222. for (k = 0; k < dz->fltcnt; k++ ) {
  3223. xx = (double) ((2.0 * (k+1)) - 1.0);
  3224. aa = -sin(xx * ss);
  3225. tppwr = pow(tp,2.0);
  3226. cc = 1.0 - (2.0 * aa * tp) + tppwr;
  3227. x1 = 2.0 * (tppwr - 1.0)/cc ;
  3228. x2 = (1.0 + (2.0 * aa * tp) + tppwr)/cc ;
  3229. dz->parray[fbase + FLT_DEN1][k] = signd * x1;
  3230. dz->parray[fbase + FLT_DEN2][k] = -x2 ;
  3231. dz->parray[fbase + FLT_CN][k] = pow(tp,2.0)/cc ;
  3232. }
  3233. }
  3234. /********************************* INITIALISE_FILTER_COEFFS_LPHP *****************************/
  3235. void initialise_filter_coeffs_lphp(dataptr dz)
  3236. {
  3237. int k;
  3238. int i,index;
  3239. int fbase = dz->outlevs + 1;
  3240. for (k = 0 ; k < dz->iparam[FLT_CNT]; k++) {
  3241. dz->parray[fbase + FLT_S1_BASE][k] = 0.0;
  3242. dz->parray[fbase + FLT_S2_BASE][k] = 0.0;
  3243. dz->parray[fbase + FLT_E1_BASE][k] = 0.0;
  3244. dz->parray[fbase + FLT_E2_BASE][k] = 0.0;
  3245. }
  3246. for(i=1;i < STEREO; i++){
  3247. index = i * FLT_LPHP_ARRAYS_PER_FILTER;
  3248. for (k = 0 ; k < dz->iparam[FLT_CNT]; k++) {
  3249. dz->parray[fbase + FLT_S1_BASE + index][k] = 0.0;
  3250. dz->parray[fbase + FLT_S2_BASE + index][k] = 0.0;
  3251. dz->parray[fbase + FLT_E1_BASE + index][k] = 0.0;
  3252. dz->parray[fbase + FLT_E2_BASE + index][k] = 0.0;
  3253. }
  3254. }
  3255. }
  3256. ////
  3257. // HEREH When do we start the filtering ??
  3258. // How do we use the finishing strategy for the filter tail ??
  3259. // How do we test whether filter works (output filter !!!!)
  3260. /**************************** ESTABLISH_ECHOS ***************************
  3261. void establish_echos(int *maxdelay,dataptr dz)
  3262. {
  3263. int n;
  3264. double *delay = dz->parray[dz->echobas]; // size 20
  3265. double *gainl = dz->parray[dz->echobas + 1]; // size 20
  3266. double *gainr = dz->parray[dz->echobas + 2]; // size 20
  3267. double tdelay[] = {0.131832, 0.215038, 0.322274, 0.414122, 0.504488, 0.637713, 0.730468, 0.808751, 0.910460, 1.027041, 1.132028, 1.244272, 1.336923, 1.427700, 1.528503, 1.618661, 1.715413, 1.814730, 1.914843, 2.000258};
  3268. double gain[] = {0.500000,0.354813,0.354813,0.251189,0.125893,0.125893,0.063096,0.063096,0.031623,0.031623,0.012589,0.012589,0.005012,0.005012,0.002512,0.002512,0.002512,0.002512,0.002512,0.002512};
  3269. double pan[] = {.9,.5,-.5,0.1,.7,-.7,.3,-.3,.15,-.15,.85,-.85,.4,-.4,.6,-.6,.225,-.225,.775,-.775};
  3270. for(n=0;n < dz->iparam[FRAC_ECHOCNT]; n++)
  3271. delay[n] = (int)round(tdelay[n] * dz->infile->srate * dz->param[STAD_SIZE]) * STEREO;
  3272. *maxdelay = delay[dz->iparam[FRAC_ECHOCNT - 1]];
  3273. if(dz->param[FRAC_EROLL]<1.0) {
  3274. for(n=0;n<dz->iparam[FRAC_ECHOCNT];n++)
  3275. gain[n] = pow(gain[n],dz->param[FRAC_EROLL]);
  3276. }
  3277. for(n=0;n<dz->iparam[FRAC_ECHOCNT];n++) {
  3278. if(pan[n] < 0.0) { // LEFTWARDS
  3279. gainl[n] = gain[n] * dz->param[FRAC_EPREGN];
  3280. gainr[n] = gain[n] * dz->param[FRAC_EPREGN] * (1.0+pan[n]);
  3281. } else { // RIGHTWARDS
  3282. gainl[n] = gain[n] * dz->param[FRAC_EPREGN] * (1.0-pan[n]);
  3283. gainr[n] = gain[n] * dz->param[FRAC_EPREGN];
  3284. }
  3285. }
  3286. }
  3287. */