mchanpan.c 191 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643
  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 <float.h>
  24. #include <structures.h>
  25. #include <tkglobals.h>
  26. #include <pnames.h>
  27. #include <filetype.h>
  28. #include <processno.h>
  29. #include <modeno.h>
  30. #include <logic.h>
  31. #include <globcon.h>
  32. #include <cdpmain.h>
  33. #include <math.h>
  34. #include <mixxcon.h>
  35. #include <osbind.h>
  36. #include <standalone.h>
  37. #include <ctype.h>
  38. #include <sfsys.h>
  39. #include <string.h>
  40. #include <srates.h>
  41. //#ifdef unix
  42. #define round(x) lround((x))
  43. //#endif
  44. #ifndef HUGE
  45. #define HUGE 3.40282347e+38F
  46. #endif
  47. char errstr[2400];
  48. int anal_infiles = 1;
  49. int sloom = 0;
  50. int sloombatch = 0;
  51. /* TW update 2012 */
  52. const char* cdp_version = "7.1.0";
  53. //CDP LIB REPLACEMENTS
  54. static int setup_mchanpan_application(dataptr dz);
  55. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  56. static int parse_infile_and_check_type(char **cmdline,dataptr dz);
  57. static int check_the_param_validity_and_consistency(dataptr dz);
  58. static int setup_mchanpan_param_ranges_and_defaults(dataptr dz);
  59. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz);
  60. static int open_the_outfile(dataptr dz);
  61. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  62. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  63. static int establish_application(dataptr dz);
  64. static int initialise_vflags(dataptr dz);
  65. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  66. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  67. static int mark_parameter_types(dataptr dz,aplptr ap);
  68. static int assign_file_data_storage(int infilecnt,dataptr dz);
  69. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  70. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  71. static int get_the_mode_from_cmdline(char *str,dataptr dz);
  72. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  73. //static double dbtolevel(double val);
  74. static int mchanpan(dataptr dz);
  75. static int allocate_mchanpan_buffer(dataptr dz);
  76. static void mchan_pancalc(double position,double *leftgain,double *rightgain,double *farleftgain,double *farrightgain,int *leftchan,int pantype,int focusparam,dataptr dz);
  77. static int newposition(int *brkindex,double *position,double *posincr,int *total_sams,int *true_goalchan,int *pantype,dataptr dz);
  78. static int read_mchanpan_data(char *filename,dataptr dz);
  79. static int read_mchancross_data(char *filename,dataptr dz);
  80. static int count_events(int silpar,int arrayno,int *arraycnt,dataptr dz);
  81. static void spread_set(dataptr dz);
  82. static void spread_pan(double *centre,dataptr dz);
  83. static int read_antiphon_data(char *filename,dataptr dz);
  84. static int setup_antiphon_arrays(char *str,dataptr dz);
  85. static int generate_antiphonal_events_array(dataptr dz);
  86. static void do_span(int *map,double span,float *ibuf,float *obuf,int bufpos,double rolloff,int chans);
  87. static int establish_arrays(dataptr dz);
  88. static void spread_pan_array_cnt(double time,int last,dataptr dz);
  89. static int spread_pan_process(double time,int last,dataptr dz);
  90. static int write_break_data(dataptr dz);
  91. static int handle_the_special_data(int *cmdlinecnt,char ***cmdline,dataptr dz);
  92. static int zing(dataptr dz);
  93. static int stepspread(dataptr dz);
  94. static int panspread(dataptr dz);
  95. static int antiphonal_events(dataptr dz);
  96. static int antiphony(dataptr dz);
  97. static int crosspan(dataptr dz);
  98. static int panprocess(dataptr dz);
  99. static int mchanpan2(dataptr dz);
  100. static void permute_chans(int outchans,dataptr dz);
  101. static void insertch(int n,int t,int outchans,dataptr dz);
  102. static void prefixch(int n,int outchans,dataptr dz);
  103. static void shuflupch(int k,int outchans,dataptr dz);
  104. static int adjacence(int endchan,dataptr dz);
  105. #define BSIZE (128)
  106. #define ROOT2 (1.4142136)
  107. #define ASCTOINT (96)
  108. #define ATCENTRE (0)
  109. #define TOCENTRE (1)
  110. #define FROMCENTRE (2)
  111. #define CROSSCENTRE (3)
  112. #define ATEDGE (4)
  113. #define antiphlen0 itemcnt
  114. #define antiphlen1 ringsize
  115. #define antievents rampbrksize
  116. /* GENERAL SCHEMA FOR ROTATION PANNING ON > 2 LOUDSPEAKERS
  117. *
  118. * (homc = hole in middle compensation)
  119. *
  120. * 0.05 0.9 0.05 0
  121. * x x cross x x
  122. * ~ \ + / ~
  123. * ~ \ homc / ~
  124. * ~ \ / ~ cross
  125. * ~ X ~ linear
  126. * ~ / \ ~
  127. * ~ / \ ~
  128. * ~ / \ ~
  129. * 0 0.05 0.9 0.05
  130. * x x x x
  131. *
  132. *
  133. * If there are only 3 channels
  134. * 0.05 0.9 0.05
  135. * x x cross x
  136. * homc
  137. * 0.05 0.05 0.9
  138. * x x x cross
  139. * homc
  140. * 0.9 0.05 0.05
  141. * x x x
  142. *
  143. * So, effectively, the 3rd channel does not change in level
  144. * But we get the same effect by crossfading between
  145. * Chan N (0.05) and chan (N+3)%3 (==N in this case) (0.05)
  146. * So same algo applies to 3-channel case.
  147. *
  148. * HOMC: this may vary, depending on which lspkrs one's panning between ???
  149. *
  150. * For 4 lpskrs, pan position can be at lspkr 1 2 3 4
  151. * or in between (1.5, 2.7, 4.9)
  152. *
  153. * Best way to think of this is as (lspkr - 1) % chans
  154. * i.e. 0 1 2 3 or in between (.5 1.7 3.9)
  155. * USing "mod" allows us to have an increasing lspkr position (on e.g. 4 lpskrs)
  156. * which circles the space, so (1->4->5), so the parameter is 0->3->4 % 4 = 0->3->0
  157. *
  158. * So fileformat can be
  159. * Time lspkrposition
  160. * 0.0 1
  161. * 2.2 3
  162. * 2.6 4.5
  163. * 10 1.3
  164. *
  165. * Rotation can be generated using a time-increasing parameter, to generate the file
  166. * such that eveytime position == whole number, create a time-position pair, and using
  167. * ((lspkr - 1)%chancnt + 1) to give correct lspkr.
  168. *
  169. * For any position, e.g. 3.5 the output is
  170. * LEFTCHAN = floor(3.5) = chan 3
  171. * RIGHTCHAN = LEFTCHAN + 1;
  172. * HOMC param controlled by 3.5 - floor(3.5) = stereoposition
  173. * level on L-1 = 0.05 * (1.0 - K)
  174. * level on R+1 = 0.05 * K
  175. * level on any remaining loudspeakers = 0
  176. *
  177. */
  178. /**************************************** MAIN *********************************************/
  179. int main(int argc,char *argv[]) // THIS ALL NEEDS TO BE FIXED !!! */
  180. {
  181. int exit_status;
  182. dataptr dz = NULL;
  183. char **cmdline;
  184. int cmdlinecnt;
  185. int n;
  186. //aplptr ap;
  187. int is_launched = FALSE;
  188. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  189. fprintf(stdout,"%s\n",cdp_version);
  190. fflush(stdout);
  191. return 0;
  192. }
  193. /* CHECK FOR SOUNDLOOM */
  194. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  195. sloom = 0;
  196. sloombatch = 1;
  197. }
  198. if(sflinit("cdp")){
  199. sfperror("cdp: initialisation\n");
  200. return(FAILED);
  201. }
  202. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  203. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  204. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  205. return(FAILED);
  206. }
  207. if(!sloom) {
  208. if(argc == 1) {
  209. usage1();
  210. return(FAILED);
  211. } else if(argc == 2) {
  212. usage2(argv[1]);
  213. return(FAILED);
  214. }
  215. }
  216. dz->maxmode = 10;
  217. if(!sloom) {
  218. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  219. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  220. return(FAILED);
  221. }
  222. cmdline = argv;
  223. cmdlinecnt = argc;
  224. if((get_the_process_no(argv[0],dz))<0)
  225. return(FAILED);
  226. cmdline++;
  227. cmdlinecnt--;
  228. if((exit_status = get_the_mode_from_cmdline(cmdline[0],dz))<0) {
  229. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  230. return(FAILED);
  231. }
  232. cmdline++;
  233. cmdlinecnt--;
  234. // setup_particular_application =
  235. if((exit_status = setup_mchanpan_application(dz))<0) {
  236. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  237. return(FAILED);
  238. }
  239. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  240. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  241. return(FAILED);
  242. }
  243. } else {
  244. //parse_TK_data() =
  245. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  246. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  247. return(exit_status);
  248. }
  249. }
  250. //ap = dz->application;
  251. // parse_infile_and_hone_type() =
  252. if((exit_status = parse_infile_and_check_type(cmdline,dz))<0) {
  253. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  254. return(FAILED);
  255. }
  256. if(dz->mode == 7) {
  257. if((exit_status = establish_arrays(dz))<0) {
  258. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  259. return(FAILED);
  260. }
  261. }
  262. // setup_param_ranges_and_defaults() =
  263. if((exit_status = setup_mchanpan_param_ranges_and_defaults(dz))<0) {
  264. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  265. return(FAILED);
  266. }
  267. // open_first_infile CDP LIB
  268. if((exit_status = open_first_infile(cmdline[0],dz))<0) {
  269. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  270. return(FAILED);
  271. }
  272. cmdlinecnt--;
  273. cmdline++;
  274. if(dz->infilecnt > 1) {
  275. if(dz->mode == 5) {
  276. if((exit_status = handle_extra_infiles(&cmdline,&cmdlinecnt,dz))<0) {
  277. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  278. return(FAILED);
  279. }
  280. } else {
  281. sprintf(errstr,"This process uses only one input file\n");
  282. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  283. return(FAILED);
  284. }
  285. }
  286. // handle_extra_infiles() : redundant
  287. // handle_outfile() =
  288. if(dz->mode != 7) {
  289. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,dz))<0) {
  290. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  291. return(FAILED);
  292. }
  293. }
  294. // handle_formants() redundant
  295. // handle_formant_quiksearch() redundant
  296. // handle_special_data() redundant
  297. if(dz->mode == 0 || dz->mode == 1 || dz->mode == 4 || dz->mode == 5 || dz->mode == 6) {
  298. if((exit_status = handle_the_special_data(&cmdlinecnt,&cmdline,dz))<0) {
  299. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  300. return(FAILED);
  301. }
  302. }
  303. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  304. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  305. return(FAILED);
  306. }
  307. // check_param_validity_and_consistency
  308. if((exit_status = check_the_param_validity_and_consistency(dz))<0) {
  309. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  310. return(FAILED);
  311. }
  312. if(dz->mode != 7) {
  313. if((exit_status = open_the_outfile(dz))<0) { // outfile opened here as output chancnt is a parameter
  314. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  315. return(FAILED);
  316. }
  317. }
  318. is_launched = TRUE;
  319. if(dz->mode != 7) {
  320. if(dz->mode == 6)
  321. dz->bufcnt = dz->infile->channels * 2;
  322. else
  323. dz->bufcnt = (dz->infile->channels * dz->infilecnt) + dz->iparam[0];
  324. if((dz->sampbuf = (float **)malloc(sizeof(float *) * (dz->bufcnt+1)))==NULL) {
  325. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffers.\n");
  326. return(MEMORY_ERROR);
  327. }
  328. if((dz->sbufptr = (float **)malloc(sizeof(float *) * dz->bufcnt))==NULL) {
  329. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffer pointers.\n");
  330. return(MEMORY_ERROR);
  331. }
  332. for(n = 0;n <dz->bufcnt; n++)
  333. dz->sampbuf[n] = dz->sbufptr[n] = (float *)0;
  334. dz->sampbuf[n] = (float *)0;
  335. if((exit_status = allocate_mchanpan_buffer(dz))<0) {
  336. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  337. return(FAILED);
  338. }
  339. }
  340. //param_preprocess() redundant
  341. //spec_process_file =
  342. switch(dz->mode) {
  343. case(0):
  344. if((exit_status = mchanpan(dz))<0) {
  345. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  346. return(FAILED);
  347. }
  348. break;
  349. case(1):
  350. case(9):
  351. if((exit_status = zing(dz))<0) {
  352. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  353. return(FAILED);
  354. }
  355. break;
  356. case(2):
  357. if((exit_status = stepspread(dz))<0) {
  358. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  359. return(FAILED);
  360. }
  361. break;
  362. case(3):
  363. if((exit_status = panspread(dz))<0) {
  364. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  365. return(FAILED);
  366. }
  367. break;
  368. case(4):
  369. if((exit_status = antiphonal_events(dz))<0) {
  370. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  371. return(FAILED);
  372. }
  373. break;
  374. case(5):
  375. if((exit_status = antiphony(dz))<0) {
  376. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  377. return(FAILED);
  378. }
  379. break;
  380. case(6):
  381. if((exit_status = crosspan(dz))<0) {
  382. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  383. return(FAILED);
  384. }
  385. break;
  386. case(7):
  387. if((exit_status = panprocess(dz))<0) {
  388. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  389. return(FAILED);
  390. }
  391. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  392. free(dz);
  393. return(SUCCEEDED);
  394. case(8):
  395. if((exit_status = mchanpan2(dz))<0) {
  396. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  397. return(FAILED);
  398. }
  399. break;
  400. }
  401. if(dz->mode != 6)
  402. dz->infile->channels = dz->iparam[0]; // ready for output header
  403. if((exit_status = complete_output(dz))<0) { // CDP LIB
  404. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  405. return(FAILED);
  406. }
  407. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  408. free(dz);
  409. return(SUCCEEDED);
  410. }
  411. /**********************************************
  412. REPLACED CDP LIB FUNCTIONS
  413. **********************************************/
  414. /****************************** SET_PARAM_DATA *********************************/
  415. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  416. {
  417. ap->special_data = (char)special_data;
  418. ap->param_cnt = (char)paramcnt;
  419. ap->max_param_cnt = (char)maxparamcnt;
  420. if(ap->max_param_cnt>0) {
  421. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  422. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  423. return(MEMORY_ERROR);
  424. }
  425. strcpy(ap->param_list,paramlist);
  426. }
  427. return(FINISHED);
  428. }
  429. /****************************** SET_VFLGS *********************************/
  430. int set_vflgs
  431. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  432. {
  433. ap->option_cnt = (char) optcnt; /*RWD added cast */
  434. if(optcnt) {
  435. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  436. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  437. return(MEMORY_ERROR);
  438. }
  439. strcpy(ap->option_list,optlist);
  440. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  441. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  442. return(MEMORY_ERROR);
  443. }
  444. strcpy(ap->option_flags,optflags);
  445. }
  446. ap->vflag_cnt = (char) vflagcnt;
  447. ap->variant_param_cnt = (char) vparamcnt;
  448. if(vflagcnt) {
  449. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  450. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  451. return(MEMORY_ERROR);
  452. }
  453. strcpy(ap->variant_list,varlist);
  454. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  455. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  456. return(MEMORY_ERROR);
  457. }
  458. strcpy(ap->variant_flags,varflags);
  459. }
  460. return(FINISHED);
  461. }
  462. /***************************** APPLICATION_INIT **************************/
  463. int application_init(dataptr dz)
  464. {
  465. int exit_status;
  466. int storage_cnt;
  467. int tipc, brkcnt;
  468. aplptr ap = dz->application;
  469. if(ap->vflag_cnt>0)
  470. initialise_vflags(dz);
  471. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  472. ap->total_input_param_cnt = (char)tipc;
  473. if(tipc>0) {
  474. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  475. return(exit_status);
  476. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  477. return(exit_status);
  478. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  479. return(exit_status);
  480. }
  481. brkcnt = tipc;
  482. //THERE ARE NO INPUTFILE brktables USED IN THIS PROCESS
  483. if(brkcnt>0) {
  484. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  485. return(exit_status);
  486. }
  487. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  488. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  489. return(exit_status);
  490. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  491. return(exit_status);
  492. }
  493. if((exit_status = mark_parameter_types(dz,ap))<0)
  494. return(exit_status);
  495. // establish_infile_constants() replaced by
  496. // dz->infilecnt = 1;
  497. if(dz->mode != 7) {
  498. if((exit_status = setup_internal_arrays_and_array_pointers(dz))<0)
  499. return(exit_status);
  500. }
  501. //establish_bufptrs_and_extra_buffers():
  502. return(FINISHED);
  503. }
  504. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  505. /* RWD mallo changed to calloc; helps debug verison run as release! */
  506. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  507. {
  508. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  509. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  510. return(MEMORY_ERROR);
  511. }
  512. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  513. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  514. return(MEMORY_ERROR);
  515. }
  516. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  517. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  518. return(MEMORY_ERROR);
  519. }
  520. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  521. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  522. return(MEMORY_ERROR);
  523. }
  524. return(FINISHED);
  525. }
  526. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  527. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  528. {
  529. int n;
  530. for(n=0;n<storage_cnt;n++) {
  531. dz->is_int[n] = (char)0;
  532. dz->no_brk[n] = (char)0;
  533. }
  534. return(FINISHED);
  535. }
  536. /***************************** MARK_PARAMETER_TYPES **************************/
  537. int mark_parameter_types(dataptr dz,aplptr ap)
  538. {
  539. int n, m; /* PARAMS */
  540. for(n=0;n<ap->max_param_cnt;n++) {
  541. switch(ap->param_list[n]) {
  542. case('0'): break; /* dz->is_active[n] = 0 is default */
  543. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  544. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  545. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  546. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  547. default:
  548. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  549. return(PROGRAM_ERROR);
  550. }
  551. } /* OPTIONS */
  552. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  553. switch(ap->option_list[n]) {
  554. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  555. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  556. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  557. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  558. default:
  559. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  560. return(PROGRAM_ERROR);
  561. }
  562. } /* VARIANTS */
  563. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  564. switch(ap->variant_list[n]) {
  565. case('0'): break;
  566. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  567. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  568. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  569. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  570. default:
  571. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  572. return(PROGRAM_ERROR);
  573. }
  574. } /* INTERNAL */
  575. for(n=0,
  576. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  577. switch(ap->internal_param_list[n]) {
  578. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  579. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  580. case('d'): dz->no_brk[m] = (char)1; break;
  581. default:
  582. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  583. return(PROGRAM_ERROR);
  584. }
  585. }
  586. return(FINISHED);
  587. }
  588. /************************ HANDLE_THE_OUTFILE *********************/
  589. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz)
  590. {
  591. char *filename = (*cmdline)[0];
  592. if(filename[0]=='-' && filename[1]=='f') {
  593. dz->floatsam_output = 1;
  594. dz->true_outfile_stype = SAMP_FLOAT;
  595. filename+= 2;
  596. }
  597. if(!sloom) {
  598. if(file_has_invalid_startchar(filename) || value_is_numeric(filename)) {
  599. sprintf(errstr,"Outfile name %s has invalid start character(s) or looks too much like a number.\n",filename);
  600. return(DATA_ERROR);
  601. }
  602. }
  603. if((dz->outfilename = (char *)malloc(strlen(filename) + 1))==NULL) {
  604. sprintf(errstr,"No memory to store output filename.\n");
  605. return(DATA_ERROR);
  606. }
  607. strcpy(dz->outfilename,filename);
  608. (*cmdline)++;
  609. (*cmdlinecnt)--;
  610. return(FINISHED);
  611. }
  612. /************************ OPEN_THE_OUTFILE *********************/
  613. int open_the_outfile(dataptr dz)
  614. {
  615. int exit_status, k;
  616. k = dz->infile->channels;
  617. if(dz->mode != 6)
  618. dz->infile->channels = dz->iparam[0];
  619. if((exit_status = create_sized_outfile(dz->outfilename,dz))<0)
  620. return(exit_status);
  621. dz->infile->channels = k;
  622. return(FINISHED);
  623. }
  624. /************************ HANDLE_THE_SPECIAL_DATA *********************/
  625. int handle_the_special_data(int *cmdlinecnt,char ***cmdline,dataptr dz)
  626. {
  627. int exit_status;
  628. aplptr ap = dz->application;
  629. // if(ap->special_data) {
  630. if(!sloom) {
  631. if(*cmdlinecnt <= 0) {
  632. sprintf(errstr,"Insufficient parameters on command line.\n");
  633. return(USAGE_ONLY);
  634. }
  635. }
  636. switch(dz->mode) {
  637. case(0):
  638. case(1):
  639. ap->min_special = 0;
  640. ap->max_special = 16;
  641. ap->min_special2 = -1;
  642. ap->max_special2 = 1;
  643. if((exit_status = read_mchanpan_data((*cmdline)[0],dz))<0)
  644. return(exit_status);
  645. break;
  646. case(4):
  647. case(5):
  648. if((exit_status = read_antiphon_data((*cmdline)[0],dz))<0)
  649. return(exit_status);
  650. break;
  651. case(6):
  652. if((exit_status = read_mchancross_data((*cmdline)[0],dz))<0)
  653. return(exit_status);
  654. break;
  655. }
  656. (*cmdline)++;
  657. (*cmdlinecnt)--;
  658. // }
  659. return(FINISHED);
  660. }
  661. /***************************** ESTABLISH_APPLICATION **************************/
  662. int establish_application(dataptr dz)
  663. {
  664. aplptr ap;
  665. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  666. sprintf(errstr,"establish_application()\n");
  667. return(MEMORY_ERROR);
  668. }
  669. ap = dz->application;
  670. memset((char *)ap,0,sizeof(struct applic));
  671. return(FINISHED);
  672. }
  673. /************************* INITIALISE_VFLAGS *************************/
  674. int initialise_vflags(dataptr dz)
  675. {
  676. int n;
  677. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  678. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  679. return(MEMORY_ERROR);
  680. }
  681. for(n=0;n<dz->application->vflag_cnt;n++)
  682. dz->vflag[n] = FALSE;
  683. return FINISHED;
  684. }
  685. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  686. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  687. {
  688. int n;
  689. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  690. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  691. return(MEMORY_ERROR);
  692. }
  693. for(n=0;n<tipc;n++)
  694. ap->default_val[n] = 0.0;
  695. return(FINISHED);
  696. }
  697. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  698. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  699. {
  700. int n;
  701. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  702. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  703. return(MEMORY_ERROR);
  704. }
  705. for(n=0;n<tipc;n++)
  706. dz->is_active[n] = (char)0;
  707. return(FINISHED);
  708. }
  709. /************************* PARSE_INFILE_AND_CHECK_TYPE *******************/
  710. int parse_infile_and_check_type(char **cmdline,dataptr dz)
  711. {
  712. int exit_status;
  713. infileptr infile_info;
  714. if(!sloom) {
  715. if((infile_info = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  716. sprintf(errstr,"INSUFFICIENT MEMORY for infile structure to test file data.");
  717. return(MEMORY_ERROR);
  718. } else if((exit_status = cdparse(cmdline[0],infile_info))<0) {
  719. sprintf(errstr,"Failed to parse input file %s\n",cmdline[0]);
  720. return(PROGRAM_ERROR);
  721. } else if(infile_info->filetype != SNDFILE) {
  722. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  723. return(DATA_ERROR);
  724. }
  725. switch(dz->mode) {
  726. case(0):
  727. case(1):
  728. case(2):
  729. case(9):
  730. if(infile_info->channels != 1) {
  731. sprintf(errstr,"File %s is not of correct type (must be mono)\n",cmdline[0]);
  732. return(DATA_ERROR);
  733. }
  734. break;
  735. case(3):
  736. if(infile_info->channels > 2) {
  737. sprintf(errstr,"File %s is not of correct type (must be mono or stereo)\n",cmdline[0]);
  738. return(DATA_ERROR);
  739. }
  740. break;
  741. case(6):
  742. case(7):
  743. if(infile_info->channels < 2) {
  744. sprintf(errstr,"File %s is not of correct type (cannot be mono)\n",cmdline[0]);
  745. return(DATA_ERROR);
  746. }
  747. break;
  748. }
  749. if((exit_status = copy_parse_info_to_main_structure(infile_info,dz))<0) {
  750. sprintf(errstr,"Failed to copy file parsing information\n");
  751. return(PROGRAM_ERROR);
  752. }
  753. free(infile_info);
  754. }
  755. return(FINISHED);
  756. }
  757. /********************************* PARSE_SLOOM_DATA *********************************/
  758. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  759. {
  760. int exit_status;
  761. int cnt = 1, infilecnt;
  762. int filesize, insams, inbrksize;
  763. double dummy;
  764. int true_cnt = 0;
  765. //aplptr ap;
  766. while(cnt<=PRE_CMDLINE_DATACNT) {
  767. if(cnt > argc) {
  768. sprintf(errstr,"Insufficient data sent from TK\n");
  769. return(DATA_ERROR);
  770. }
  771. switch(cnt) {
  772. case(1):
  773. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  774. sprintf(errstr,"Cannot read process no. sent from TK\n");
  775. return(DATA_ERROR);
  776. }
  777. break;
  778. case(2):
  779. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  780. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  781. return(DATA_ERROR);
  782. }
  783. if(dz->mode > 0)
  784. dz->mode--;
  785. //setup_particular_application() =
  786. if((exit_status = setup_mchanpan_application(dz))<0)
  787. return(exit_status);
  788. //ap = dz->application;
  789. break;
  790. case(3):
  791. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  792. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  793. return(DATA_ERROR);
  794. }
  795. if(infilecnt < 1) {
  796. true_cnt = cnt + 1;
  797. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  798. }
  799. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  800. return(exit_status);
  801. break;
  802. case(INPUT_FILETYPE+4):
  803. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  804. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  805. return(DATA_ERROR);
  806. }
  807. break;
  808. case(INPUT_FILESIZE+4):
  809. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  810. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  811. return(DATA_ERROR);
  812. }
  813. dz->insams[0] = filesize;
  814. break;
  815. case(INPUT_INSAMS+4):
  816. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  817. sprintf(errstr,"Cannot read insams sent from TK\n");
  818. return(DATA_ERROR);
  819. }
  820. dz->insams[0] = insams;
  821. break;
  822. case(INPUT_SRATE+4):
  823. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  824. sprintf(errstr,"Cannot read srate sent from TK\n");
  825. return(DATA_ERROR);
  826. }
  827. break;
  828. case(INPUT_CHANNELS+4):
  829. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  830. sprintf(errstr,"Cannot read channels sent from TK\n");
  831. return(DATA_ERROR);
  832. }
  833. break;
  834. case(INPUT_STYPE+4):
  835. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  836. sprintf(errstr,"Cannot read stype sent from TK\n");
  837. return(DATA_ERROR);
  838. }
  839. break;
  840. case(INPUT_ORIGSTYPE+4):
  841. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  842. sprintf(errstr,"Cannot read origstype sent from TK\n");
  843. return(DATA_ERROR);
  844. }
  845. break;
  846. case(INPUT_ORIGRATE+4):
  847. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  848. sprintf(errstr,"Cannot read origrate sent from TK\n");
  849. return(DATA_ERROR);
  850. }
  851. break;
  852. case(INPUT_MLEN+4):
  853. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  854. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  855. return(DATA_ERROR);
  856. }
  857. break;
  858. case(INPUT_DFAC+4):
  859. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  860. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  861. return(DATA_ERROR);
  862. }
  863. break;
  864. case(INPUT_ORIGCHANS+4):
  865. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  866. sprintf(errstr,"Cannot read origchans sent from TK\n");
  867. return(DATA_ERROR);
  868. }
  869. break;
  870. case(INPUT_SPECENVCNT+4):
  871. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  872. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  873. return(DATA_ERROR);
  874. }
  875. dz->specenvcnt = dz->infile->specenvcnt;
  876. break;
  877. case(INPUT_WANTED+4):
  878. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  879. sprintf(errstr,"Cannot read wanted sent from TK\n");
  880. return(DATA_ERROR);
  881. }
  882. break;
  883. case(INPUT_WLENGTH+4):
  884. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  885. sprintf(errstr,"Cannot read wlength sent from TK\n");
  886. return(DATA_ERROR);
  887. }
  888. break;
  889. case(INPUT_OUT_CHANS+4):
  890. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  891. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  892. return(DATA_ERROR);
  893. }
  894. break;
  895. /* RWD these chanegs to samps - tk will have to deal with that! */
  896. case(INPUT_DESCRIPTOR_BYTES+4):
  897. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  898. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  899. return(DATA_ERROR);
  900. }
  901. break;
  902. case(INPUT_IS_TRANSPOS+4):
  903. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  904. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  905. return(DATA_ERROR);
  906. }
  907. break;
  908. case(INPUT_COULD_BE_TRANSPOS+4):
  909. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  910. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  911. return(DATA_ERROR);
  912. }
  913. break;
  914. case(INPUT_COULD_BE_PITCH+4):
  915. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  916. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  917. return(DATA_ERROR);
  918. }
  919. break;
  920. case(INPUT_DIFFERENT_SRATES+4):
  921. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  922. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  923. return(DATA_ERROR);
  924. }
  925. break;
  926. case(INPUT_DUPLICATE_SNDS+4):
  927. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  928. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  929. return(DATA_ERROR);
  930. }
  931. break;
  932. case(INPUT_BRKSIZE+4):
  933. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  934. sprintf(errstr,"Cannot read brksize sent from TK\n");
  935. return(DATA_ERROR);
  936. }
  937. if(inbrksize > 0) {
  938. switch(dz->input_data_type) {
  939. case(WORDLIST_ONLY):
  940. break;
  941. case(PITCH_AND_PITCH):
  942. case(PITCH_AND_TRANSPOS):
  943. case(TRANSPOS_AND_TRANSPOS):
  944. dz->tempsize = inbrksize;
  945. break;
  946. case(BRKFILES_ONLY):
  947. case(UNRANGED_BRKFILE_ONLY):
  948. case(DB_BRKFILES_ONLY):
  949. case(ALL_FILES):
  950. case(ANY_NUMBER_OF_ANY_FILES):
  951. if(dz->extrabrkno < 0) {
  952. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  953. return(DATA_ERROR);
  954. }
  955. if(dz->brksize == NULL) {
  956. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  957. return(PROGRAM_ERROR);
  958. }
  959. dz->brksize[dz->extrabrkno] = inbrksize;
  960. break;
  961. default:
  962. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  963. dz->input_data_type);
  964. return(PROGRAM_ERROR);
  965. }
  966. break;
  967. }
  968. break;
  969. case(INPUT_NUMSIZE+4):
  970. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  971. sprintf(errstr,"Cannot read numsize sent from TK\n");
  972. return(DATA_ERROR);
  973. }
  974. break;
  975. case(INPUT_LINECNT+4):
  976. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  977. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  978. return(DATA_ERROR);
  979. }
  980. break;
  981. case(INPUT_ALL_WORDS+4):
  982. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  983. sprintf(errstr,"Cannot read all_words sent from TK\n");
  984. return(DATA_ERROR);
  985. }
  986. break;
  987. case(INPUT_ARATE+4):
  988. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  989. sprintf(errstr,"Cannot read arate sent from TK\n");
  990. return(DATA_ERROR);
  991. }
  992. break;
  993. case(INPUT_FRAMETIME+4):
  994. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  995. sprintf(errstr,"Cannot read frametime sent from TK\n");
  996. return(DATA_ERROR);
  997. }
  998. dz->frametime = (float)dummy;
  999. break;
  1000. case(INPUT_WINDOW_SIZE+4):
  1001. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  1002. sprintf(errstr,"Cannot read window_size sent from TK\n");
  1003. return(DATA_ERROR);
  1004. }
  1005. break;
  1006. case(INPUT_NYQUIST+4):
  1007. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  1008. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  1009. return(DATA_ERROR);
  1010. }
  1011. break;
  1012. case(INPUT_DURATION+4):
  1013. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  1014. sprintf(errstr,"Cannot read duration sent from TK\n");
  1015. return(DATA_ERROR);
  1016. }
  1017. break;
  1018. case(INPUT_MINBRK+4):
  1019. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  1020. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  1021. return(DATA_ERROR);
  1022. }
  1023. break;
  1024. case(INPUT_MAXBRK+4):
  1025. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  1026. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  1027. return(DATA_ERROR);
  1028. }
  1029. break;
  1030. case(INPUT_MINNUM+4):
  1031. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  1032. sprintf(errstr,"Cannot read minnum sent from TK\n");
  1033. return(DATA_ERROR);
  1034. }
  1035. break;
  1036. case(INPUT_MAXNUM+4):
  1037. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  1038. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  1039. return(DATA_ERROR);
  1040. }
  1041. break;
  1042. default:
  1043. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  1044. return(PROGRAM_ERROR);
  1045. }
  1046. cnt++;
  1047. }
  1048. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  1049. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  1050. return(DATA_ERROR);
  1051. }
  1052. if(true_cnt)
  1053. cnt = true_cnt;
  1054. *cmdlinecnt = 0;
  1055. while(cnt < argc) {
  1056. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  1057. return(exit_status);
  1058. cnt++;
  1059. }
  1060. return(FINISHED);
  1061. }
  1062. /********************************* GET_TK_CMDLINE_WORD *********************************/
  1063. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  1064. {
  1065. if(*cmdlinecnt==0) {
  1066. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  1067. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  1068. return(MEMORY_ERROR);
  1069. }
  1070. } else {
  1071. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  1072. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  1073. return(MEMORY_ERROR);
  1074. }
  1075. }
  1076. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  1077. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  1078. return(MEMORY_ERROR);
  1079. }
  1080. strcpy((*cmdline)[*cmdlinecnt],q);
  1081. (*cmdlinecnt)++;
  1082. return(FINISHED);
  1083. }
  1084. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  1085. int assign_file_data_storage(int infilecnt,dataptr dz)
  1086. {
  1087. int exit_status;
  1088. int no_sndfile_system_files = FALSE;
  1089. dz->infilecnt = infilecnt;
  1090. if((exit_status = allocate_filespace(dz))<0)
  1091. return(exit_status);
  1092. if(no_sndfile_system_files)
  1093. dz->infilecnt = 0;
  1094. return(FINISHED);
  1095. }
  1096. /************************* redundant functions: to ensure libs compile OK *******************/
  1097. int assign_process_logic(dataptr dz)
  1098. {
  1099. return(FINISHED);
  1100. }
  1101. void set_legal_infile_structure(dataptr dz)
  1102. {}
  1103. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  1104. {
  1105. return(FINISHED);
  1106. }
  1107. int establish_bufptrs_and_extra_buffers(dataptr dz)
  1108. {
  1109. return(FINISHED);
  1110. }
  1111. int read_special_data(char *str,dataptr dz)
  1112. {
  1113. return(FINISHED);
  1114. }
  1115. int inner_loop
  1116. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  1117. {
  1118. return(FINISHED);
  1119. }
  1120. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1121. {
  1122. return(FINISHED);
  1123. }
  1124. /************************* SETUP_INTERNAL_ARRAYS_AND_ARRAY_POINTERS *******************/
  1125. int setup_internal_arrays_and_array_pointers(dataptr dz)
  1126. {
  1127. switch(dz->mode) {
  1128. case(0):
  1129. dz->array_cnt = 1;
  1130. if((dz->parray = (double **)malloc(dz->array_cnt * sizeof(double *)))==NULL) {
  1131. sprintf(errstr,"INSUFFICIENT MEMORY for internal long arrays.\n");
  1132. return(MEMORY_ERROR);
  1133. }
  1134. dz->parray[0] = NULL;
  1135. break;
  1136. case(1):
  1137. dz->larray_cnt = 2;
  1138. if((dz->lparray = (int **)malloc(dz->larray_cnt * sizeof(int *)))==NULL) {
  1139. sprintf(errstr,"INSUFFICIENT MEMORY for internal long arrays.\n");
  1140. return(MEMORY_ERROR);
  1141. }
  1142. dz->lparray[0] = NULL;
  1143. dz->lparray[1] = NULL;
  1144. break;
  1145. case(2):
  1146. dz->larray_cnt = 1;
  1147. dz->array_cnt = 2;
  1148. if((dz->lparray = (int **)malloc(dz->larray_cnt * sizeof(int *)))==NULL) {
  1149. sprintf(errstr,"INSUFFICIENT MEMORY for internal long arrays.\n");
  1150. return(MEMORY_ERROR);
  1151. }
  1152. dz->lparray[0] = NULL;
  1153. if((dz->parray = (double **)malloc(dz->array_cnt * sizeof(double *)))==NULL) {
  1154. sprintf(errstr,"INSUFFICIENT MEMORY for internal double arrays.\n");
  1155. return(MEMORY_ERROR);
  1156. }
  1157. dz->parray[0] = NULL;
  1158. dz->parray[1] = NULL;
  1159. break;
  1160. case(3):
  1161. dz->array_cnt = 1;
  1162. if((dz->parray = (double **)malloc(dz->array_cnt * sizeof(double *)))==NULL) {
  1163. sprintf(errstr,"INSUFFICIENT MEMORY for internal double arrays.\n");
  1164. return(MEMORY_ERROR);
  1165. }
  1166. dz->parray[0] = NULL;
  1167. break;
  1168. case(4):
  1169. case(5):
  1170. dz->larray_cnt = 3;
  1171. if((dz->lparray = (int **)malloc(dz->larray_cnt * sizeof(int *)))==NULL) {
  1172. sprintf(errstr,"INSUFFICIENT MEMORY for internal long arrays.\n");
  1173. return(MEMORY_ERROR);
  1174. }
  1175. dz->lparray[0] = NULL;
  1176. dz->lparray[1] = NULL;
  1177. dz->lparray[2] = NULL;
  1178. break;
  1179. case(6):
  1180. dz->larray_cnt = 2;
  1181. if((dz->lparray = (int **)malloc(dz->larray_cnt * sizeof(int *)))==NULL) {
  1182. sprintf(errstr,"INSUFFICIENT MEMORY for internal long arrays.\n");
  1183. return(MEMORY_ERROR);
  1184. }
  1185. dz->lparray[0] = NULL;
  1186. dz->lparray[1] = NULL;
  1187. break;
  1188. case(9):
  1189. dz->larray_cnt = 1;
  1190. if((dz->lparray = (int **)malloc(dz->larray_cnt * sizeof(int *)))==NULL) {
  1191. sprintf(errstr,"INSUFFICIENT MEMORY for internal long arrays.\n");
  1192. return(MEMORY_ERROR);
  1193. }
  1194. dz->lparray[0] = NULL;
  1195. dz->iarray_cnt = 1;
  1196. if((dz->iparray = (int **)malloc(dz->iarray_cnt * sizeof(int *)))==NULL) {
  1197. sprintf(errstr,"INSUFFICIENT MEMORY for internal int arrays.\n");
  1198. return(MEMORY_ERROR);
  1199. }
  1200. dz->iparray[0] = NULL;
  1201. break;
  1202. }
  1203. return(FINISHED);
  1204. }
  1205. /******************************** ESTABLISH_ARRAYS ********************************/
  1206. int establish_arrays(dataptr dz)
  1207. {
  1208. int n;
  1209. dz->array_cnt = 2 + dz->infile->channels;
  1210. if((dz->parray = (double **)malloc(dz->array_cnt * sizeof(double *)))==NULL) {
  1211. sprintf(errstr,"INSUFFICIENT MEMORY for internal double arrays.\n");
  1212. return(MEMORY_ERROR);
  1213. }
  1214. for(n=0;n < dz->array_cnt;n++)
  1215. dz->parray[n] = NULL;
  1216. dz->larray_cnt = 4;
  1217. if((dz->lparray = (int **)malloc(dz->larray_cnt * sizeof(int *)))==NULL) {
  1218. sprintf(errstr,"INSUFFICIENT MEMORY for internal long arrays.\n");
  1219. return(MEMORY_ERROR);
  1220. }
  1221. for(n=0;n < dz->larray_cnt;n++)
  1222. dz->lparray[n] = NULL;
  1223. return(FINISHED);
  1224. }
  1225. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  1226. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  1227. {
  1228. int n;
  1229. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1230. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  1231. return(MEMORY_ERROR);
  1232. }
  1233. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1234. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  1235. return(MEMORY_ERROR);
  1236. }
  1237. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1238. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  1239. return(MEMORY_ERROR);
  1240. }
  1241. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1242. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  1243. return(MEMORY_ERROR);
  1244. }
  1245. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1246. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  1247. return(MEMORY_ERROR);
  1248. }
  1249. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1250. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  1251. return(MEMORY_ERROR);
  1252. }
  1253. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1254. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  1255. return(MEMORY_ERROR);
  1256. }
  1257. for(n=0;n<brkcnt;n++) {
  1258. dz->brk[n] = NULL;
  1259. dz->brkptr[n] = NULL;
  1260. dz->brkinit[n] = 0;
  1261. dz->brksize[n] = 0;
  1262. }
  1263. return(FINISHED);
  1264. }
  1265. /******************************** USAGE1 ********************************/
  1266. int usage1(void)
  1267. {
  1268. usage2("mchanpan");
  1269. return(USAGE_ONLY);
  1270. }
  1271. /******************************** USAGE2 ********************************/
  1272. int usage2(char *str)
  1273. {
  1274. if(!strcmp(str,"mchanpan")) {
  1275. fprintf(stderr,
  1276. "USAGE: mchanpan mchanpan 1 inf outf panfile outchans [-ffocus]\n"
  1277. "USAGE: mchanpan mchanpan 2 inf outf switchdata outchans [-ffocus -mminsil]\n"
  1278. "USAGE: mchanpan mchanpan 3 inf outf outchans centre spread depth rolloff minsil [-s]\n"
  1279. "USAGE: mchanpan mchanpan 4 inf outf outchans centre spread depth rolloff\n"
  1280. "USAGE: mchanpan mchanpan 5 inf outf antiphon outchans minsil\n"
  1281. "USAGE: mchanpan mchanpan 6 inf1 [inf2 ..] outf antiphon outchans eventdur gap splice\n"
  1282. "USAGE: mchanpan mchanpan 7 inf outf pandata rolloff\n"
  1283. "USAGE: mchanpan mchanpan 9 inf outf outchans startchan speed focus [-a]\n"
  1284. "USAGE: mchanpan mchanpan 10 inf outf outchans [-ffocus -mminsil -ggrouping] [-a] [-r]\n"
  1285. "\n"
  1286. "Mode 1: Move a mono sound file around a multichannel space.\n"
  1287. "Mode 2: Switch (silence-separated) mono events in file from one chan to another.\n"
  1288. "Mode 3: Spread (s-s) mono events stepwise from one set of chans, to another set.\n"
  1289. "Mode 4: Spread source gradually from a centre, across several channels.\n"
  1290. "Mode 5: Switch events antiphonally between 2 specified sets of channels.\n"
  1291. "Mode 6: Switch sounds antiphonally between 2 specified sets of channels.\n"
  1292. " Mode 6 can take 1 or more inputfiles.\n"
  1293. "Mode 7: Pan from one channel configuration to another, passing through centre.\n"
  1294. "Mode 9: Rotate a mono sound file around a multichannel space.\n"
  1295. "Mode 10: Switch (silence-separated) mono events randomly from one chan to another.\n"
  1296. "\n"
  1297. "PANFILE Output pan-data in triples: time pan-position pantype\n"
  1298. " Pan-position vals lie between (channel) 1 and a max no-of-channels >= 3.\n"
  1299. " positions between 0 and 1 are also possible (see below).\n"
  1300. "\n"
  1301. " Pantype values can be\n"
  1302. " 0 = direct pan: pan from 1 to 4 goes directly between lspkrs 1->4\n"
  1303. " 1 = clockwise rotation: pan 1 to 4 goes around lspkrs 1->2->3->4\n"
  1304. " -1 = anticlock rotation: pan 1 to 4 (with 8 chans) goes 1->8->7->6->5->4\n"
  1305. "\n"
  1306. " Direct pans must start at single lspkr:\n"
  1307. " and position vals must be non-zero integers.\n"
  1308. "\n"
  1309. " Rotations can start/stop anywhere, so position values can be fractional.\n"
  1310. " Vals between 0 & 1 are positions between max lspkr (e.g. 8) and lspkr 1\n"
  1311. "\n"
  1312. "SWITCHDATA list of outchans, in a textfile. Sound switches from one outchan to next.\n"
  1313. " If end of list reached, it starts again from its beginning.\n"
  1314. "\n"
  1315. "PANDATA Output pan-data in lines, each having: time pan-positions\n"
  1316. " Pan-positions is a list of ALL the input channels, in any order.\n"
  1317. " Each input channel in turn is mapped to each numbered channel in the list.\n"
  1318. " Passing from one mapping to next, sound in all chans spreads out until it's\n"
  1319. " output equally from all chans, then contracts to its next outchan position.\n"
  1320. " To force this maximal spread elsewehere,\n"
  1321. " enter time & list of zeros (1 for each chan).\n"
  1322. "\n"
  1323. "ANTIPHON two strings of letters, with separator ('-') represents antiphonal chans.\n"
  1324. " e.g. abcd-efgh = antiphon between chans 1,2,3,4 and chans 5,6,7,8.\n"
  1325. "\n"
  1326. "OUTCHANS number of channels in the output file.\n"
  1327. "\n"
  1328. "STARTCHAN mode 8: Channel from which rotation begins.\n"
  1329. "\n"
  1330. "SPEED mode 8: Speed of rotation (cycles per sec): can vary through time.\n"
  1331. "\n"
  1332. "FOCUS If focus = 1.0, position (e.g.) '2' puts all signal in lspkr 2\n"
  1333. " If focus = 0.9, position '2' puts 0.9 of signal in lspkr 2\n"
  1334. " and the remainder in the 2 adjacent lspkrs (1 and 3).\n"
  1335. "\n"
  1336. "MINSIL min duration (mS) of zero-value samps to count as silence between peaks.\n"
  1337. "CENTRE centre of spreading. Time-variable.\n"
  1338. "SPREAD Chan-spread of output (far left to far right of centre). Time-variable.\n"
  1339. " Minimum is 1 in Mode 3 and 0 in Mode 4.\n"
  1340. "DEPTH max no of chans (to left, and to right) utilised, behind leading edges.\n"
  1341. " Signal always reaches maximum spread, but may have hole in middle. \n"
  1342. "ROLLOFF level fall as signal spread over several chans. Range 0-1.\n"
  1343. " 0 = no fall in level, 1 = level divided by number of chans in use.\n"
  1344. "EVENTDUR Time before switching to next outchannel set(can timevary).\n"
  1345. "GAP Time gap between switching events (can timevary).\n"
  1346. "SPLICE Duration (in mS) of splices cutting events.\n"
  1347. "GROUPING (Max) number of events at outchan, before switch to next outchan.\n"
  1348. "-s Output steps wider by 1 channel (to both L & R) on every event,\n"
  1349. " as far as the spread value given (must be integer).\n"
  1350. " Depth value must also be integer.\n"
  1351. "-a Mode 8: ANTICLOCKWISE rotation (default clockwise).\n"
  1352. " Mode 10: no steps allowed between ADJACENT output channels.\n"
  1353. "-r Mode 10: Randomise number of grouped events at each outchan.\n");
  1354. } else
  1355. fprintf(stderr,"Unknown option '%s'\n",str);
  1356. return(USAGE_ONLY);
  1357. }
  1358. int usage3(char *str1,char *str2)
  1359. {
  1360. fprintf(stderr,"Insufficient parameters on command line.\n");
  1361. return(USAGE_ONLY);
  1362. }
  1363. /********************************************************************************************/
  1364. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1365. {
  1366. if(!strcmp(prog_identifier_from_cmdline,"mchanpan")) {
  1367. dz->process = MCHANPAN;
  1368. } else {
  1369. sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  1370. return(USAGE_ONLY);
  1371. }
  1372. return(FINISHED);
  1373. }
  1374. /************************************ READ_MCHANPAN_DATA ************************************/
  1375. int read_mchanpan_data(char *filename,dataptr dz)
  1376. {
  1377. double *p, *time, *position, *type, lasttime, maxpos, dummy;
  1378. int n, k, outchans, itype, ipos, cnt;
  1379. int *snake;
  1380. char temp[200], *q;
  1381. aplptr ap;
  1382. FILE *fp;
  1383. ap = dz->application;
  1384. if((fp = fopen(filename,"r"))==NULL) {
  1385. sprintf(errstr, "Can't open file %s to read data.\n",filename);
  1386. return(DATA_ERROR);
  1387. }
  1388. cnt = 0;
  1389. while(fgets(temp,200,fp)==temp) {
  1390. q = temp;
  1391. if(*q == ';') // Allow comments in file
  1392. continue;
  1393. while(get_float_from_within_string(&q,&dummy)) {
  1394. cnt++;
  1395. }
  1396. }
  1397. if(cnt == 0) {
  1398. sprintf(errstr,"No data in file %s\n",filename);
  1399. return(DATA_ERROR);
  1400. }
  1401. switch(dz->mode) {
  1402. case(0):
  1403. if(((dz->ringsize = cnt/3) * 3) != cnt) {
  1404. sprintf(errstr,"Data not grouped correctly in file %s\n",filename);
  1405. return(DATA_ERROR);
  1406. }
  1407. if((dz->parray[0] = (double *)malloc(cnt * sizeof(double)))==NULL) {
  1408. sprintf(errstr,"INSUFFICIENT MEMORY for data in file %s.\n",filename);
  1409. return(MEMORY_ERROR);
  1410. }
  1411. time = dz->parray[0];
  1412. position = time+1;
  1413. type = time+2;
  1414. rewind(fp);
  1415. lasttime = -1.0;
  1416. cnt = 0;
  1417. while(fgets(temp,200,fp)==temp) {
  1418. q = temp;
  1419. if(*q == ';') // Allow comments in file
  1420. continue;
  1421. while(get_float_from_within_string(&q,&dummy)) {
  1422. switch(cnt) {
  1423. case(0):
  1424. if(dummy < 0.0 || dummy <= lasttime) {
  1425. sprintf(errstr,"Times do not advance correctly in file %s.\n",filename);
  1426. return(DATA_ERROR);
  1427. }
  1428. *time = dummy;
  1429. time += 3;
  1430. break;
  1431. case(1):
  1432. if(dummy < ap->min_special || dummy > ap->max_special) {
  1433. sprintf(errstr,"Invalid position value (%lf) in file %s.\n",dummy,filename);
  1434. return(DATA_ERROR);
  1435. }
  1436. *position = dummy;
  1437. position += 3;
  1438. break;
  1439. case(2):
  1440. if(dummy < ap->min_special2 || dummy > ap->max_special2) {
  1441. sprintf(errstr,"Invalid pantytpe value (%lf) in file %s.\n",dummy,filename);
  1442. return(DATA_ERROR);
  1443. }
  1444. k = (int)round(dummy);
  1445. if((double)k != dummy) {
  1446. sprintf(errstr,"Invalid pantytpe value (%lf) in file %s.\n",dummy,filename);
  1447. return(DATA_ERROR);
  1448. }
  1449. *type = dummy;
  1450. type += 3;
  1451. break;
  1452. }
  1453. cnt++;
  1454. cnt %= 3;
  1455. }
  1456. }
  1457. if(fclose(fp)<0) {
  1458. fprintf(stdout,"WARNING: Failed to close file %s.\n",filename);
  1459. fflush(stdout);
  1460. }
  1461. maxpos = -DBL_MAX;
  1462. p = dz->parray[0];
  1463. p++;
  1464. for(n=0;n<dz->ringsize;n++) {
  1465. if(*p > maxpos)
  1466. maxpos = *p;
  1467. p+=3;
  1468. }
  1469. outchans = (int)ceil(maxpos);
  1470. // if(outchans < 3) {
  1471. // sprintf(errstr,"Less than 3 output channels required: this process is for panning over 3 or more channels only.\n");
  1472. // return(DATA_ERROR);
  1473. // }
  1474. dz->itemcnt = outchans;
  1475. time = dz->parray[0];
  1476. position = time+1;
  1477. type = time+2;
  1478. for(n=0;n<dz->ringsize;n++) {
  1479. itype = (int)round(*type);
  1480. if(itype == 0) {
  1481. ipos = (int)round(*position);
  1482. if((double)ipos != *position) {
  1483. sprintf(errstr,"Non-integer position (%lf) associated with a direct pan, at line %d.\n",*position,n+1);
  1484. return(DATA_ERROR);
  1485. }
  1486. }
  1487. time += 3;
  1488. position += 3;
  1489. type += 3;
  1490. }
  1491. break;
  1492. case(1):
  1493. if((dz->lparray[0] = (int *)malloc(cnt * sizeof(int)))==NULL) {
  1494. sprintf(errstr,"INSUFFICIENT MEMORY for data in file %s.\n",filename);
  1495. return(MEMORY_ERROR);
  1496. }
  1497. snake = dz->lparray[0];
  1498. dz->itemcnt = 0;
  1499. rewind(fp);
  1500. cnt = 0;
  1501. while(fgets(temp,200,fp)==temp) {
  1502. q = temp;
  1503. if(*q == ';') // Allow comments in file
  1504. continue;
  1505. while(get_float_from_within_string(&q,&dummy)) {
  1506. if((snake[cnt] = (int)round(dummy)) < 1) {
  1507. sprintf(errstr,"Invalid channel number (%d) in snake data.\n",snake[cnt]);
  1508. return(MEMORY_ERROR);
  1509. }
  1510. dz->itemcnt = max(dz->itemcnt,snake[cnt]); // dz->itemcnt stores max channel referred to in listing
  1511. cnt++;
  1512. }
  1513. }
  1514. dz->ringsize = cnt; // dz->ringsize stores number of items in listing
  1515. if(fclose(fp)<0) {
  1516. fprintf(stdout,"WARNING: Failed to close file %s.\n",filename);
  1517. fflush(stdout);
  1518. }
  1519. break;
  1520. }
  1521. return(FINISHED);
  1522. }
  1523. /************************************ READ_MCHANCROSS_DATA ************************************/
  1524. int read_mchancross_data(char *filename,dataptr dz)
  1525. {
  1526. double time = 0.0, lasttime = -1.0, dummy, srate = (double)dz->infile->srate;
  1527. int n, m, k, chans = dz->infile->channels, cnt;
  1528. int *events, *maps;
  1529. int eventcnt, mapcnt, thischan;
  1530. char temp[200], *q;
  1531. FILE *fp;
  1532. fprintf(stdout,"INFO: Checking panning data\n");
  1533. fflush(stdout);
  1534. if((fp = fopen(filename,"r"))==NULL) {
  1535. sprintf(errstr, "Can't open file %s to read data.\n",filename);
  1536. return(DATA_ERROR);
  1537. }
  1538. cnt = 0;
  1539. while(fgets(temp,200,fp)==temp) {
  1540. q = temp;
  1541. if(*q == ';') // Allow comments in file
  1542. continue;
  1543. while(get_float_from_within_string(&q,&dummy)) {
  1544. cnt++;
  1545. }
  1546. }
  1547. if(cnt == 0) {
  1548. sprintf(errstr,"No data in file %s\n",filename);
  1549. return(DATA_ERROR);
  1550. }
  1551. k = dz->infile->channels + 1;
  1552. if ((dz->itemcnt = cnt/k) * k != cnt) {
  1553. sprintf(errstr, "Data in file %s not grouped correctly.\n",filename);
  1554. return(DATA_ERROR);
  1555. }
  1556. dz->ringsize = cnt - dz->itemcnt;
  1557. if((dz->lparray[0] = (int *)malloc((dz->itemcnt + 2) * sizeof(int)))==NULL) {
  1558. sprintf(errstr,"INSUFFICIENT MEMORY for data in file %s.\n",filename);
  1559. return(MEMORY_ERROR);
  1560. }
  1561. if((dz->lparray[1] = (int *)malloc((dz->ringsize + (2 * chans)) * sizeof(int)))==NULL) {
  1562. sprintf(errstr,"INSUFFICIENT MEMORY for data in file %s.\n",filename);
  1563. return(MEMORY_ERROR);
  1564. }
  1565. events = dz->lparray[0];
  1566. maps = dz->lparray[1];
  1567. rewind(fp);
  1568. cnt = 0;
  1569. eventcnt = 0;
  1570. mapcnt = 0;
  1571. while(fgets(temp,200,fp)==temp) {
  1572. q = temp;
  1573. if(*q == ';') // Allow comments in file
  1574. continue;
  1575. while(get_float_from_within_string(&q,&dummy)) {
  1576. if(cnt % k == 0) {
  1577. time = dummy;
  1578. if(eventcnt == 0) {
  1579. if(time < 0.0) {
  1580. sprintf(errstr,"Invalid time (%lf) in file %s\n",time, filename);
  1581. return(DATA_ERROR);
  1582. }
  1583. } else if(time <= lasttime) {
  1584. sprintf(errstr,"Times do not increase between (%lf) and %lf in file %s\n",lasttime, time, filename);
  1585. return(DATA_ERROR);
  1586. }
  1587. if(eventcnt >= dz->itemcnt) {
  1588. sprintf(errstr,"Accounting error 1 in reading crosspan data\n");
  1589. return(PROGRAM_ERROR);
  1590. }
  1591. events[eventcnt++] = (int)round(time * srate) * chans;
  1592. lasttime = time;
  1593. } else {
  1594. thischan = (int)round(dummy);
  1595. if(thischan < 0 || thischan > chans) {
  1596. sprintf(errstr,"Invalid channel (%d) at time %lf in file %s\n",thischan, time, filename);
  1597. return(DATA_ERROR);
  1598. }
  1599. thischan--;
  1600. if(mapcnt >= dz->ringsize) {
  1601. sprintf(errstr,"Accounting error 2 in reading crosspan data\n");
  1602. return(PROGRAM_ERROR);
  1603. }
  1604. maps[mapcnt++] = thischan;
  1605. }
  1606. cnt++;
  1607. }
  1608. }
  1609. if(fclose(fp)<0) {
  1610. fprintf(stdout,"WARNING: Failed to close file %s.\n",filename);
  1611. fflush(stdout);
  1612. }
  1613. for(mapcnt=0,k=0;mapcnt<dz->ringsize;mapcnt+=chans,k++) {
  1614. if(maps[mapcnt] >= 0) {
  1615. for(n=0;n<chans;n++) {
  1616. if(maps[mapcnt+n] < 0) {
  1617. sprintf(errstr,"Zero channel entries can only be used for EVERY line in a map (see time %lf)\n",(double)(events[k]/chans)/srate);
  1618. return(DATA_ERROR);
  1619. }
  1620. }
  1621. for(n=0;n<chans-1;n++) {
  1622. for(m = n+1;m<chans;m++) {
  1623. if(maps[mapcnt+n] == maps[mapcnt+m]) {
  1624. sprintf(errstr,"Channel %d duplicated at time %lf\n",maps[mapcnt+n]+1,(double)(events[k]/chans)/srate);
  1625. return(DATA_ERROR);
  1626. }
  1627. }
  1628. }
  1629. } else {
  1630. for(n=0;n<chans;n++) {
  1631. if(maps[mapcnt+n] >= 0) {
  1632. sprintf(errstr,"Zero channel entries can only be used for EVERY line in a map (see time %lf)\n",(double)(events[k]/chans)/srate);
  1633. return(DATA_ERROR);
  1634. }
  1635. }
  1636. }
  1637. }
  1638. if(events[0] > 0) { // If ness, insert an event at tome 0
  1639. for(n=dz->itemcnt-1;n>=0;n--)
  1640. events[n+1] = events[n]; // Copy all times to next higher place
  1641. events[0] = 0; // Insert time 0 at foot of array
  1642. dz->itemcnt++; // Increment count of events
  1643. for(n=dz->ringsize - 1;n>=0;n-=chans) // Copy all maps to next higher map-place
  1644. maps[n+chans] = maps[n]; // This also leaves a copy of lowest map where it is
  1645. dz->ringsize += chans; // Increment count of map items by length of maps
  1646. }
  1647. if(events[dz->itemcnt - 1] < dz->insams[0]) { // If ness, insert event at end of file
  1648. events[dz->itemcnt] = dz->insams[0];
  1649. dz->itemcnt++;
  1650. for(n=0;n<chans;n++) // As a copy of the final data map
  1651. maps[dz->ringsize + n] = maps[dz->ringsize - chans + n];
  1652. dz->ringsize += chans;
  1653. }
  1654. return(FINISHED);
  1655. }
  1656. /************************* SETUP_MCHANPAN_APPLICATION *******************/
  1657. int setup_mchanpan_application(dataptr dz)
  1658. {
  1659. int exit_status;
  1660. aplptr ap;
  1661. if((exit_status = establish_application(dz))<0) // GLOBAL
  1662. return(FAILED);
  1663. ap = dz->application;
  1664. // SEE parstruct FOR EXPLANATION of next 2 functions
  1665. switch(dz->mode) {
  1666. case(0):
  1667. if((exit_status = set_param_data(ap,MCHANDATA ,1,1,"i"))<0)
  1668. return(FAILED);
  1669. if((exit_status = set_vflgs(ap,"",0,"","f",1,1,"d"))<0)
  1670. return(FAILED);
  1671. break;
  1672. case(1):
  1673. if((exit_status = set_param_data(ap,MCHANDATA2 ,1,1,"i"))<0)
  1674. return(FAILED);
  1675. if((exit_status = set_vflgs(ap,"",0,"","fm",2,2,"dd"))<0)
  1676. return(FAILED);
  1677. break;
  1678. case(2):
  1679. if((exit_status = set_param_data(ap,0,6,6,"iDDDDd"))<0)
  1680. return(FAILED);
  1681. if((exit_status = set_vflgs(ap,"",0,"","s",1,0,"0"))<0)
  1682. return(FAILED);
  1683. break;
  1684. case(3):
  1685. if((exit_status = set_param_data(ap,0,5,5,"iiDDD"))<0)
  1686. return(FAILED);
  1687. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  1688. return(FAILED);
  1689. break;
  1690. case(4):
  1691. if((exit_status = set_param_data(ap,ANTIPHON,2,2,"id"))<0)
  1692. return(FAILED);
  1693. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  1694. return(FAILED);
  1695. break;
  1696. case(5):
  1697. if((exit_status = set_param_data(ap,ANTIPHON,4,4,"iDDd"))<0)
  1698. return(FAILED);
  1699. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  1700. return(FAILED);
  1701. break;
  1702. case(6):
  1703. if((exit_status = set_param_data(ap,CROSSPAN,1,1,"D"))<0)
  1704. return(FAILED);
  1705. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  1706. return(FAILED);
  1707. break;
  1708. case(7):
  1709. if((exit_status = set_param_data(ap,0,2,2,"DD"))<0)
  1710. return(FAILED);
  1711. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  1712. return(FAILED);
  1713. break;
  1714. case(8):
  1715. if((exit_status = set_param_data(ap,0,4,4,"iiDd"))<0)
  1716. return(FAILED);
  1717. if((exit_status = set_vflgs(ap,"",0,"","a",1,0,"0"))<0)
  1718. return(FAILED);
  1719. break;
  1720. case(9):
  1721. if((exit_status = set_param_data(ap,0 ,1,1,"i"))<0)
  1722. return(FAILED);
  1723. if((exit_status = set_vflgs(ap,"fmg",3,"ddI","ar",2,0,"00"))<0)
  1724. return(FAILED);
  1725. break;
  1726. }
  1727. // set_legal_infile_structure -->
  1728. dz->has_otherfile = FALSE;
  1729. // assign_process_logic -->
  1730. if(dz->mode == 7) {
  1731. dz->input_data_type = SNDFILES_ONLY;
  1732. dz->process_type = OTHER_PROCESS;
  1733. dz->outfiletype = NO_OUTPUTFILE;
  1734. return application_init(dz); //GLOBAL
  1735. }
  1736. if(dz->mode == 5)
  1737. dz->input_data_type = ONE_OR_MANY_SNDFILES;
  1738. else
  1739. dz->input_data_type = SNDFILES_ONLY;
  1740. dz->process_type = UNEQUAL_SNDFILE;
  1741. dz->outfiletype = SNDFILE_OUT;
  1742. return application_init(dz); //GLOBAL
  1743. }
  1744. /************************* SETUP_MCHANPAN_PARAM_RANGES_AND_DEFAULTS *******************/
  1745. int setup_mchanpan_param_ranges_and_defaults(dataptr dz)
  1746. {
  1747. int exit_status;
  1748. aplptr ap = dz->application;
  1749. // set_param_ranges()
  1750. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  1751. // NB total_input_param_cnt is > 0 !!!
  1752. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  1753. return(FAILED);
  1754. // get_param_ranges()
  1755. if(dz->mode == 6) {
  1756. ap->lo[0] = 0;
  1757. ap->hi[0] = 1;
  1758. ap->default_val[0] = 1;
  1759. } else {
  1760. ap->lo[0] = 3;
  1761. ap->hi[0] = 16;
  1762. ap->default_val[0] = 8;
  1763. }
  1764. switch(dz->mode) {
  1765. case(9):
  1766. ap->lo[3] = 1;
  1767. ap->hi[3] = 100;
  1768. ap->default_val[3] = 1;
  1769. /* fall thro */
  1770. case(1):
  1771. ap->lo[2] = (2.0/(double)dz->infile->srate) * SECS_TO_MS;
  1772. ap->hi[2] = (32767.0/(double)dz->infile->srate) * SECS_TO_MS;
  1773. ap->default_val[2] = SILMIN;
  1774. /* fall thro */
  1775. case(0):
  1776. ap->lo[1] = 0;
  1777. ap->hi[1] = 1;
  1778. ap->default_val[1] = 1;
  1779. break;
  1780. case(2):
  1781. ap->lo[5] = (2.0/(double)dz->infile->srate) * SECS_TO_MS; // inter-event silence
  1782. ap->hi[5] = (32767.0/(double)dz->infile->srate) * SECS_TO_MS;
  1783. ap->default_val[5] = SILMIN;
  1784. /* fall thro */
  1785. case(3):
  1786. ap->lo[1] = 0.0; // centre
  1787. ap->hi[1] = 8.0;
  1788. ap->default_val[1] = 1;
  1789. ap->lo[2] = 0.0; // spread
  1790. ap->hi[2] = 16.0;
  1791. ap->default_val[2] = 8;
  1792. ap->lo[3] = 0.0; // maxdepth
  1793. ap->hi[3] = 8;
  1794. ap->default_val[3] = 4;
  1795. ap->lo[4] = 0.0; // rolloff
  1796. ap->hi[4] = 1.0;
  1797. ap->default_val[4] = 0.0;
  1798. break;
  1799. case(4):
  1800. ap->lo[1] = (2.0/(double)dz->infile->srate) * SECS_TO_MS;
  1801. ap->hi[1] = (32767.0/(double)dz->infile->srate) * SECS_TO_MS;
  1802. ap->default_val[1] = SILMIN;
  1803. break;
  1804. case(5):
  1805. ap->lo[1] = 0.0;
  1806. ap->hi[1] = 60.0;
  1807. ap->default_val[1] = 0.5;
  1808. ap->lo[2] = 0.0;
  1809. ap->hi[2] = 60.0;
  1810. ap->default_val[2] = 0.0;
  1811. ap->lo[3] = 0.0;
  1812. ap->hi[3] = 1000.0;
  1813. ap->default_val[3] = 15.0;
  1814. break;
  1815. case(7):
  1816. ap->lo[0] = 0.0;
  1817. ap->hi[0] = 16.0;
  1818. ap->default_val[0] = 1.0;
  1819. ap->lo[1] = 0.0;
  1820. ap->hi[1] = 16.0;
  1821. ap->default_val[1] = 0.0;
  1822. break;
  1823. case(8):
  1824. ap->lo[1] = 0;
  1825. ap->hi[1] = 16;
  1826. ap->default_val[1] = 1;
  1827. ap->lo[2] = 0;
  1828. ap->hi[2] = 64;
  1829. ap->default_val[2] = 1;
  1830. ap->lo[3] = 0;
  1831. ap->hi[3] = 1;
  1832. ap->default_val[3] = 1;
  1833. break;
  1834. }
  1835. if(!sloom)
  1836. put_default_vals_in_all_params(dz);
  1837. return(FINISHED);
  1838. }
  1839. /************************************************** MCHANPAN ********************************************/
  1840. #define DIRECT 0
  1841. #define ROTATION 1
  1842. int mchanpan(dataptr dz)
  1843. {
  1844. int exit_status;
  1845. int i, chan, got_newposition, step=0;
  1846. int brkindex = 1, leftchan = 1, rightchan=0, farleftchan=0, farrightchan=0, outchans = dz->iparam[0];
  1847. int startbesideleft=0, startbesideright=0, goalbesideleft=0, goalbesideright=0;
  1848. int true_goalchan = (int)round(dz->parray[0][1]), goalchan = true_goalchan - 1, startchan=0, pantype=0;
  1849. int block = 0, sams = 0, total_sams = 0;
  1850. float *inbuf = dz->sampbuf[0], *bufptr;
  1851. double leftgain,rightgain, farleftgain,farrightgain, outchansd = (double)outchans;
  1852. double lcoef = 0.0, rcoef = 0.0, llcoef = 0.0, rrcoef = 0.0, maxllcoef=0.0, factor;
  1853. double position = 0.0, posincr = 0.0, chan_multiplier;
  1854. display_virtual_time(0L,dz);
  1855. do {
  1856. if((exit_status = read_samps(inbuf,dz))<0) {
  1857. sprintf(errstr,"Failed to read data from sndfile.\n");
  1858. return(DATA_ERROR);
  1859. }
  1860. bufptr = dz->sampbuf[1]; /* set output buffer pointer */
  1861. for (i = 0 ; i < dz->ssampsread; i++ ) {
  1862. got_newposition = 0;
  1863. if(sams-- <= 0) { /* We count down in samples to the next breakpoint position value */
  1864. startchan = goalchan; /* The old gola-channel becomes the new start-channel, as we arrived at goal */
  1865. sams = newposition(&brkindex,&position,&posincr,&total_sams,&true_goalchan,&pantype,dz);
  1866. got_newposition = 1;
  1867. goalchan = true_goalchan - 1;
  1868. if(pantype == DIRECT) { /* Define channels alongside actual start and goal chans, for use where focus < 1.0 */
  1869. startbesideleft = startchan - 1; /* and sound is spread to adjacent loudspeakers */
  1870. if(startbesideleft < 0) /* NB these parameters run from 0 to outchans-less-1, where input positions run from 1 to outchans */
  1871. startbesideleft = outchans - 1;
  1872. startbesideright = startchan + 1;
  1873. if(startbesideright >= outchans)
  1874. startbesideright = 0;
  1875. goalbesideleft = goalchan - 1;
  1876. if(goalbesideleft < 0)
  1877. goalbesideleft = outchans - 1;
  1878. goalbesideright = goalchan + 1;
  1879. if(goalbesideright >= outchans)
  1880. goalbesideright = 0;
  1881. }
  1882. } /* gain data is only recalculated at each sample-block, OR when a new-position has been set */
  1883. if((block-- <= 0) || got_newposition) {
  1884. mchan_pancalc(position,&leftgain,&rightgain,&farleftgain,&farrightgain,&leftchan,pantype,1,dz);
  1885. if(pantype == ROTATION) {
  1886. leftchan--; /* output bufs numbered from 0 */
  1887. farleftchan = (leftchan + outchans - 1) % outchans; /* output chans are adjacent, L and R refer to lspkrs to left and right of current position */
  1888. rightchan = (leftchan + 1) % outchans; /* farleft and farright are speakers next to left and right spkrs, for any unfocused signal */
  1889. farrightchan = (rightchan + 1) % outchans;
  1890. }
  1891. lcoef = leftgain;
  1892. rcoef = rightgain;
  1893. llcoef = farleftgain;
  1894. rrcoef = farrightgain;
  1895. if(pantype == DIRECT) {
  1896. if(got_newposition) { /* WHERE THE FOCUS IS < 1.0, (and hence maxllcoef > 0) sounds spills to adjacent channels. */
  1897. maxllcoef = llcoef; /* lcoef, (level on startchan) does not fade to zero, nor does rcoef (level on goalchan) start at zero. */
  1898. step = abs(goalchan - startchan); /* llcoeff (level on chans adj to startchan) however ALWAYS falls to zero, at end of pan. */
  1899. }
  1900. if((step > 1) && (step != outchans - 1)) {
  1901. if(maxllcoef > 0) { /* In pans between non-adjacent loudspeakers, we use the complete fade-out of the llcoef */
  1902. factor = llcoef/maxllcoef; /* to create a 'factor' which ensures that lcoef fades completely at end of pan */
  1903. lcoef *= factor; /* and that rcoef (controlling goal-position signal) starts from zero */
  1904. rcoef *= (1.0 - factor);
  1905. } /* For adjacent-loudspeaker pans (e.g. 2->3) */
  1906. } /* llcoef & rrcoef behave differently and themselves compensate for the failure to fade to zero. */
  1907. }
  1908. block += BSIZE;
  1909. position += posincr; /* position is incremented for next block-read */
  1910. switch(pantype) {
  1911. case(DIRECT): /* In Direct pan case */
  1912. if(position > 1.0) /* position = fraction of distance between any lspkr-pair (range 0-1) */
  1913. position = 1.0;
  1914. else if(position < 0.0)
  1915. position = 0.0;
  1916. break;
  1917. case(ROTATION): /* In Rotation pan case */
  1918. if(position > outchansd) /* position = lspkr no (or some fraction inbetween) (range 1 - outchans) */
  1919. position -= outchansd; /* Convention is that vals 1 to 8 refers to positions at or between lspkrs 1-8 */
  1920. else if(position < 0.0) /* while values below 1 refer to positions between lspkr 8 and lspkr 1, in the 'circle' */
  1921. position += outchansd; /* We adjust here, when position-incrementation takes position beyond these limits */
  1922. break;
  1923. }
  1924. }
  1925. switch(pantype) {
  1926. case(DIRECT):
  1927. for(chan=0;chan<outchans;chan++) {
  1928. chan_multiplier = 0.0;
  1929. if(chan == startchan) /* output chans are not ness adjacent */
  1930. chan_multiplier += lcoef; /* 'left' & 'right' refer to start and goal of any pair of pand speakers */
  1931. if((chan == startbesideleft) && (startbesideleft != goalchan)) /* startbesideleft & startbesideright are lspkrs to left and right of start position */
  1932. chan_multiplier += llcoef; /* goalbesideleft & goalbesideright are lspkrs to left and right of goal position */
  1933. if((chan == startbesideright) && (startbesideright != goalchan)) /* these will only get signal, if focus < 1 */
  1934. chan_multiplier += llcoef; /* i.e. 2 --> 5 may imply 1 --> 4 and 3 --> 6, with lower level signal */
  1935. if(chan == goalchan)
  1936. chan_multiplier += rcoef; /* Exceptions (!= goalchan ETC) deal with case where pan is between adjacent lspkrs, */
  1937. if((chan == goalbesideleft) && (goalbesideleft != startchan)) /* and focus is < 1.0, and hence the unfocused signal and focused signal overlap. */
  1938. chan_multiplier += rrcoef; /* In General case, e.g. (1)2(3) --> (5)6(7), but in special case (1)2(3) --> (2)3(4) */
  1939. if((chan == goalbesideright) && (goalbesideright != startchan))
  1940. chan_multiplier += rrcoef; /* Amount of input signal going to this particular output channel */
  1941. *bufptr += (float)(chan_multiplier * inbuf[i]); /* is a sum of contributions depending on whether the channel is the start or goal channel */
  1942. bufptr++; /* or, where focus < 1.0, it is adjacent to the start or goal channel */
  1943. }
  1944. break;
  1945. case(ROTATION):
  1946. for(chan=0;chan<outchans;chan++) {
  1947. chan_multiplier = 0.0;
  1948. if(chan == farleftchan)
  1949. chan_multiplier += llcoef;
  1950. if(chan == leftchan)
  1951. chan_multiplier += lcoef;
  1952. if(chan == rightchan)
  1953. chan_multiplier += rcoef;
  1954. if(chan == farrightchan)
  1955. chan_multiplier += rrcoef; /* Amount of input signal going to this particular output channel */
  1956. *bufptr += (float)(chan_multiplier * inbuf[i]); /* is a sum of contributions depending on whether the channel is the start or goal channel */
  1957. bufptr++; /* or, where focus < 1.0, it is adjacent to these start or goal channel */
  1958. }
  1959. break;
  1960. }
  1961. }
  1962. if(dz->ssampsread > 0) {
  1963. if((exit_status = write_samps(dz->sampbuf[1],dz->ssampsread * outchans,dz))<0)
  1964. return(exit_status);
  1965. }
  1966. memset((char *)dz->sampbuf[1],0,dz->buflen * dz->iparam[0] * sizeof(float));
  1967. } while(dz->samps_left > 0);
  1968. return(FINISHED);
  1969. }
  1970. /************************************ NEWPOSITION *******************************/
  1971. int newposition(int *brkindex,double *position,double *posincr,int *total_sams,int *true_goalchan,int *pantype,dataptr dz)
  1972. {
  1973. double diff, steps, nextval;
  1974. double *thisbrk = dz->parray[0];
  1975. int here, sams;
  1976. double outchans = (double)dz->iparam[0];
  1977. if(*brkindex < dz->ringsize) {
  1978. here = (*brkindex) * 3;
  1979. sams = round(thisbrk[here] * dz->infile->srate) - *total_sams;
  1980. steps = (double)sams/(double)BSIZE;
  1981. *pantype = (int)round(thisbrk[here-1]);
  1982. switch(*pantype) {
  1983. case(0):
  1984. *true_goalchan = (int)round(thisbrk[here+1]); /* gets next lspkr to move to */
  1985. *position = 0; /* starts at current lspkr (notionally 0) */
  1986. *posincr = 1.0/steps; /* proceeds to next lspkr (notionally 1) */
  1987. (*brkindex)++;
  1988. break;
  1989. case(1): /* interpolates between position values in file, in increasing order */
  1990. *position = thisbrk[here-2];
  1991. nextval = thisbrk[here+1]; /* gets next position in file */
  1992. diff = fabs(nextval - (*position)); /* steps between breakpnt positions, thro all intermediate positions */
  1993. if(nextval < *position)
  1994. diff = outchans - diff; /* in order to move thro lspkrs in increasing order, 3 to 1 means 3->4->5->6->7->8->1 */
  1995. *posincr = diff/steps; /* position gradually increments */
  1996. (*brkindex)++;
  1997. break;
  1998. case(-1): /* interpolates between position values in file, in DEcreasing order */
  1999. *position = thisbrk[here-2];
  2000. nextval = thisbrk[here+1]; /* gets next position */
  2001. diff = fabs(nextval - (*position)); /* steps between breakpnt positions, thro all intermediate positions, in decreasing order */
  2002. if(nextval > *position)
  2003. diff = outchans - diff; /* in order to move thro lspkrs in DEcreasing order, 1 to 3 means 1->8->7->6->5->4->3 */
  2004. *posincr = -(diff/steps); /* position gradually DEcrements */
  2005. (*brkindex)++;
  2006. break;
  2007. }
  2008. } else {
  2009. *posincr = 0.0;
  2010. sams = dz->insams[0] - *total_sams;
  2011. }
  2012. *total_sams += sams;
  2013. if(*pantype != 0)
  2014. *pantype = 1; /* clockwise and anticlockwise rotation use the same algorithm */
  2015. return(sams);
  2016. }
  2017. /************************************ MCHAN_PANCALC *******************************/
  2018. void mchan_pancalc(double position,double *leftgain,double *rightgain,double *farleftgain,double *farrightgain,int *leftchan,int pantype,int focusparam,dataptr dz)
  2019. {
  2020. double temp;
  2021. double relpos;
  2022. double holecompensate, stereoposition, zerocentredposition;
  2023. double focus = dz->param[focusparam];
  2024. *leftchan = (int)floor(position);
  2025. stereoposition = position - (double)(*leftchan); /* range 0 to 1 */
  2026. zerocentredposition = (stereoposition * 2.0) - 1.0; /* range -1 to 1 */
  2027. if(zerocentredposition < 0)
  2028. relpos = -zerocentredposition; /* range 0 to 1 : position relative to centre of stereo */
  2029. else
  2030. relpos = zerocentredposition;
  2031. temp = 1.0 + (relpos * relpos); /* calculate hole in middle compensation */
  2032. holecompensate = ROOT2 / sqrt(temp);
  2033. *rightgain = stereoposition * holecompensate;
  2034. *leftgain = (1.0 - stereoposition) * holecompensate;
  2035. *rightgain = ((*rightgain) * focus) + dz->scalefact; /* adjust levels from range 0-1 into range 'focus' */
  2036. *leftgain = ((*leftgain) * focus) + dz->scalefact;
  2037. *farleftgain = dz->scalefact * (1.0 - stereoposition); /* calculate further-out lspkr-levels */
  2038. *farrightgain = dz->scalefact * stereoposition;
  2039. if(pantype == 1 && *leftchan == 0) /* rotations only */
  2040. *leftchan = dz->iparam[0]; /* positions below lspkr 1 are between lpskr 'outchans' and lspkr 1 */
  2041. }
  2042. /**************************** ALLOCATE_MCHANPAN_BUFFER ******************************/
  2043. int allocate_mchanpan_buffer(dataptr dz)
  2044. {
  2045. int n, m;
  2046. size_t bigbufsize;
  2047. if(dz->sbufptr == 0 || dz->sampbuf==0) {
  2048. sprintf(errstr,"buffer pointers not allocated: create_sndbufs()\n");
  2049. return(PROGRAM_ERROR);
  2050. }
  2051. bigbufsize = (size_t) Malloc(-1);
  2052. bigbufsize /= dz->bufcnt;
  2053. if(bigbufsize <=0) {
  2054. bigbufsize = F_SECSIZE * sizeof(float); /* RWD keep ths for now */
  2055. }
  2056. dz->buflen = bigbufsize / sizeof(float);
  2057. bigbufsize = dz->buflen * sizeof(float);
  2058. if((dz->bigbuf = (float *)malloc(bigbufsize * dz->bufcnt)) == NULL) {
  2059. sprintf(errstr,"INSUFFICIENT MEMORY to create sound buffers.\n");
  2060. return(PROGRAM_ERROR);
  2061. }
  2062. // We grab (N * buflen) for each N-channel infile buffer
  2063. for(m=0,n=0;n<dz->bufcnt;m++,n+=dz->infile->channels)
  2064. dz->sbufptr[m] = dz->sampbuf[m] = dz->bigbuf + (dz->buflen * n);
  2065. // And the final buffer space for the outfile buffer
  2066. dz->sampbuf[m] = dz->bigbuf + (dz->buflen * n);
  2067. dz->buflen *= dz->infile->channels; // If infile is > mono, read to a bigger buffer
  2068. return(FINISHED);
  2069. }
  2070. /**************************** CHECK_THE_PARAM_VALIDITY_AND_CONSISTENCY ****************************/
  2071. int check_the_param_validity_and_consistency(dataptr dz)
  2072. {
  2073. int exit_status;
  2074. double maxval, outchans = (double)dz->iparam[0];
  2075. switch(dz->mode) {
  2076. case(1):
  2077. dz->iparam[2] = (int)round(dz->param[2] * MS_TO_SECS * (double)dz->infile->srate);
  2078. /* fall thro */
  2079. case(0):
  2080. if(outchans < dz->itemcnt) {
  2081. sprintf(errstr,"Data file accesses more channels than specified in the 'outchans' parameter.\n");
  2082. return(DATA_ERROR);
  2083. }
  2084. dz->scalefact = (1.0 - dz->param[1])/2.0; /* Set level of signal distributed to adjacent lspkrs */
  2085. break;
  2086. case(2):
  2087. if(dz->vflag[0]) {
  2088. if(dz->brksize[1] || dz->brksize[2] || dz->brksize[3]) {
  2089. sprintf(errstr,"Brkpoint files for centre spread and depth, cannot be used when STEP flag is set\n");
  2090. return(DATA_ERROR);
  2091. }
  2092. dz->iparam[1] = (int)round(dz->param[1]);
  2093. dz->iparam[2] = (int)round(dz->param[2]);
  2094. dz->iparam[3] = (int)round(min(dz->param[3],outchans/2.0));
  2095. }
  2096. dz->iparam[5] = (int)round(dz->param[5] * MS_TO_SECS * (double)dz->infile->srate);
  2097. /* fall thro */
  2098. case(3):
  2099. if(dz->brksize[1]) {
  2100. if((exit_status = get_maxvalue_in_brktable(&maxval,1,dz))<0)
  2101. return(exit_status);
  2102. dz->param[1] = maxval;
  2103. }
  2104. if(dz->param[1] > outchans) {
  2105. sprintf(errstr,"(Max) Spread-centre value (%lf) incompatible with output channels count (%d)\n",dz->param[1],dz->iparam[0]);
  2106. return(DATA_ERROR);
  2107. }
  2108. if(dz->mode == 3) {
  2109. if(dz->brksize[1]) {
  2110. sprintf(errstr,"Brkpoint files for centre cannot be used.\n");
  2111. return(DATA_ERROR);
  2112. }
  2113. dz->iparam[1] = (int)round(dz->param[1]);
  2114. if(dz->iparam[1] != dz->param[1]) {
  2115. sprintf(errstr,"Fractional values for centre cannot be used.\n");
  2116. return(DATA_ERROR);
  2117. }
  2118. }
  2119. break;
  2120. case(4):
  2121. dz->iparam[1] = (int)round(dz->param[1] * MS_TO_SECS * (double)dz->infile->srate) * dz->infile->channels;
  2122. if((exit_status = setup_antiphon_arrays(dz->wordstor[0],dz)) < 0)
  2123. return(exit_status);
  2124. break;
  2125. case(5):
  2126. if(dz->param[1] < .05) {
  2127. sprintf(errstr,"INFO: Antiphonal steps too small\n");
  2128. return(DATA_ERROR);
  2129. }
  2130. if((exit_status = setup_antiphon_arrays(dz->wordstor[0],dz)) < 0)
  2131. return(exit_status);
  2132. if((exit_status = generate_antiphonal_events_array(dz)) < 0)
  2133. return(exit_status);
  2134. break;
  2135. case(7):
  2136. if(dz->param[0] > dz->infile->channels) {
  2137. sprintf(errstr,"Centre beyond channel count.\n");
  2138. return(DATA_ERROR);
  2139. }
  2140. if(dz->param[1] > dz->infile->channels) {
  2141. sprintf(errstr,"Spread too large for channel count.\n");
  2142. return(DATA_ERROR);
  2143. }
  2144. break;
  2145. case(8):
  2146. dz->scalefact = (1.0 - dz->param[3])/2.0; /* Set level of signal distributed to adjacent lspkrs */
  2147. if(dz->param[1] > dz->param[0]) {
  2148. sprintf(errstr,"Start Channel is too large for given channel count.\n");
  2149. return(DATA_ERROR);
  2150. }
  2151. break;
  2152. case(9):
  2153. dz->iparam[2] = (int)round(dz->param[2] * MS_TO_SECS * (double)dz->infile->srate);
  2154. dz->scalefact = (1.0 - dz->param[1])/2.0; /* Set level of signal distributed to adjacent lspkrs */
  2155. if((dz->iparray[0] = (int *)malloc(dz->iparam[0] * sizeof(int)))==NULL) {
  2156. sprintf(errstr,"INSUFFICIENT MEMORY to make channel perm array.\n");
  2157. return(MEMORY_ERROR);
  2158. }
  2159. break;
  2160. }
  2161. return(FINISHED);
  2162. }
  2163. /**************************** ZING ****************************
  2164. *
  2165. * Bounce silence-separated events in a source around a sequence of output lspkr positions.
  2166. *
  2167. */
  2168. int zing(dataptr dz)
  2169. {
  2170. int exit_status, done, permno = 0, grpno = 0, grpcnt=0, endchan = -1, eventsarray;
  2171. float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1];
  2172. int *snake = dz->lparray[0], *events;
  2173. int *perm=NULL;
  2174. int ibufpos = 0, abs_samp_pos ,buf_start, segstart, segend, k;
  2175. int snakepos = 0, outchans = dz->iparam[0];
  2176. int silsegscnt = 0, segscnt;
  2177. double smear, focus, time = 0.0, srate = (double)dz->infile->srate;
  2178. int thisoutchan, thisleftoutchan=0, thisrightoutchan=0;
  2179. focus = dz->param[1];
  2180. smear = dz->scalefact;
  2181. if(dz->mode == 9) { // Random sequence
  2182. perm = dz->iparray[0];
  2183. if(dz->brksize[3]) {
  2184. if((exit_status = read_value_from_brktable(0.0,3,dz))<0)
  2185. return(exit_status);
  2186. }
  2187. grpcnt = dz->iparam[3];
  2188. if(dz->vflag[1])
  2189. grpcnt = (int)floor(drand48() * (double)grpcnt) + 1;
  2190. }
  2191. memset((char *)obuf,0,dz->buflen * outchans * sizeof(float));
  2192. /* COUNT SILENCE-SPEARATED EVENTS IN DATA */
  2193. if(dz->mode == 9)
  2194. eventsarray = 0;
  2195. else
  2196. eventsarray = 1;
  2197. if((exit_status = count_events(2,eventsarray,&silsegscnt,dz))<0)
  2198. return(exit_status);
  2199. events = dz->lparray[eventsarray];
  2200. k = silsegscnt/2;
  2201. if(k < 2) {
  2202. sprintf(errstr,"Only one event found. No panning will take place. Try adjusting the length of silences you are using.\n");
  2203. return(DATA_ERROR);
  2204. } else {
  2205. fprintf(stdout,"INFO: %d distinct events found.\n",k);
  2206. fflush(stdout);
  2207. }
  2208. /* PAN, SWITCHING OUTCHAN FOR EACH PEAK */
  2209. fprintf(stdout,"INFO: Panning sound.\n");
  2210. fflush(stdout);
  2211. if((sndseekEx(dz->ifd[0],0,0)<0)){
  2212. sprintf(errstr,"sndseek() failed\n");
  2213. return SYSTEM_ERROR;
  2214. }
  2215. reset_filedata_counters(dz);
  2216. if((exit_status = read_samps(ibuf,dz))<0) {
  2217. sprintf(errstr,"Failed to read data from sndfile.\n");
  2218. return(DATA_ERROR);
  2219. }
  2220. if(dz->ssampsread == 0) {
  2221. sprintf(errstr,"No data found in soundfile.\n");
  2222. return(DATA_ERROR);
  2223. }
  2224. buf_start = 0;
  2225. segscnt = 0;
  2226. if(dz->mode == 9) {
  2227. do {
  2228. permute_chans(outchans,dz);
  2229. } while(adjacence(endchan,dz));
  2230. endchan = perm[outchans - 1];
  2231. thisoutchan = perm[permno];
  2232. grpno++;
  2233. } else {
  2234. thisoutchan = snake[snakepos++] - 1; /* outchans stored as 1 to N, values used as 0 to (N-1) */
  2235. snakepos %= dz->ringsize; /* cycle round lspkr positions in param-list */
  2236. }
  2237. if(smear > 0.0) {
  2238. thisleftoutchan = thisoutchan - 1;
  2239. if(thisleftoutchan < 0)
  2240. thisleftoutchan = outchans - 1;
  2241. thisrightoutchan = thisoutchan + 1;
  2242. if(thisrightoutchan >= outchans)
  2243. thisrightoutchan = 0;
  2244. }
  2245. segstart = events[segscnt++];
  2246. segend = events[segscnt++];
  2247. done = 0;
  2248. while(!done) {
  2249. while(dz->total_samps_read <= segstart) {
  2250. if((exit_status = write_samps(obuf,dz->ssampsread * outchans,dz))<0)
  2251. return(exit_status);
  2252. memset((char *)obuf,0,dz->buflen * outchans * sizeof(float));
  2253. buf_start = dz->total_samps_read;
  2254. if((exit_status = read_samps(ibuf,dz))<0) {
  2255. sprintf(errstr,"Failed to read data from sndfile.\n");
  2256. return(DATA_ERROR);
  2257. }
  2258. if(dz->ssampsread == 0) {
  2259. done = 1;
  2260. break;
  2261. }
  2262. }
  2263. if(done)
  2264. break;
  2265. ibufpos = segstart - buf_start;
  2266. abs_samp_pos = segstart;
  2267. while(abs_samp_pos < segend) {
  2268. k = (ibufpos * outchans) + thisoutchan;
  2269. obuf[k] = (float)(obuf[k] + (ibuf[ibufpos] * focus));
  2270. if(smear > 0.0) {
  2271. k = (ibufpos * outchans) + thisleftoutchan;
  2272. obuf[k] = (float)(obuf[k] + (ibuf[ibufpos] * smear));
  2273. k = (ibufpos * outchans) + thisrightoutchan;
  2274. obuf[k] = (float)(obuf[k] + (ibuf[ibufpos] * smear));
  2275. }
  2276. ibufpos++;
  2277. if(ibufpos >= dz->ssampsread) {
  2278. if((exit_status = write_samps(obuf,dz->ssampsread * outchans,dz))<0)
  2279. return(exit_status);
  2280. memset((char *)obuf,0,dz->buflen * outchans * sizeof(float));
  2281. buf_start = dz->total_samps_read;
  2282. if((exit_status = read_samps(ibuf,dz))<0) {
  2283. sprintf(errstr,"Failed to read data from sndfile.\n");
  2284. return(DATA_ERROR);
  2285. }
  2286. if(dz->ssampsread == 0) {
  2287. done = 1;
  2288. break;
  2289. }
  2290. ibufpos = 0;
  2291. }
  2292. abs_samp_pos++;
  2293. }
  2294. if(done)
  2295. break;
  2296. if(segscnt >= silsegscnt)
  2297. break;
  2298. if(dz->mode == 9) {
  2299. if(grpno >= grpcnt) {
  2300. if(dz->brksize[3]) {
  2301. time = (double)(buf_start + ibufpos)/srate;
  2302. if((exit_status = read_value_from_brktable(time,3,dz))<0)
  2303. return(exit_status);
  2304. }
  2305. grpcnt = dz->iparam[3];
  2306. if(dz->vflag[1])
  2307. grpcnt = (int)floor(drand48() * (double)grpcnt) + 1;
  2308. grpno = 0;
  2309. permno++;
  2310. }
  2311. if(permno >= outchans) {
  2312. do {
  2313. permute_chans(outchans,dz);
  2314. } while((perm[0] == endchan) || adjacence(endchan,dz));
  2315. endchan = perm[outchans - 1];
  2316. permno = 0;
  2317. }
  2318. thisoutchan = perm[permno];
  2319. grpno++;
  2320. } else {
  2321. thisoutchan = snake[snakepos++] - 1;
  2322. snakepos %= dz->ringsize;
  2323. }
  2324. if(smear > 0.0) {
  2325. thisleftoutchan = thisoutchan - 1;
  2326. if(thisleftoutchan < 0)
  2327. thisleftoutchan = outchans - 1;
  2328. thisrightoutchan = thisoutchan + 1;
  2329. if(thisrightoutchan >= outchans)
  2330. thisrightoutchan = 0;
  2331. }
  2332. segstart = events[segscnt++];
  2333. segend = events[segscnt++];
  2334. }
  2335. if(ibufpos > 0) {
  2336. if((exit_status = write_samps(dz->sampbuf[1],ibufpos * outchans,dz))<0)
  2337. return(exit_status);
  2338. }
  2339. return(FINISHED);
  2340. }
  2341. /****************************** GET_MODE *********************************/
  2342. int get_the_mode_from_cmdline(char *str,dataptr dz)
  2343. {
  2344. if(sscanf(str,"%d",&dz->mode)!=1) {
  2345. sprintf(errstr,"Cannot read mode of program.\n");
  2346. return(USAGE_ONLY);
  2347. }
  2348. if(dz->mode <= 0 || dz->mode > dz->maxmode) {
  2349. sprintf(errstr,"Program mode value [%d] is out of range [1 - %d].\n",dz->mode,dz->maxmode);
  2350. return(USAGE_ONLY);
  2351. }
  2352. dz->mode--; /* CHANGE TO INTERNAL REPRESENTATION OF MODE NO */
  2353. return(FINISHED);
  2354. }
  2355. /*************************** COUNT_EVENTS ****************************/
  2356. int count_events(int silpar,int arrayno,int *eventsegscnt,dataptr dz)
  2357. {
  2358. int exit_status;
  2359. float *ibuf = dz->sampbuf[0];
  2360. int ibufpos, last_buf_start, silstart = -1, silend;
  2361. int silsegscnt, insil, k;
  2362. int *silences, *events;
  2363. int event_at_end = 1;
  2364. /* COUNT (VALID-LENGTH) SILENCES IN DATA */
  2365. fprintf(stdout,"INFO: Counting silences between events.\n");
  2366. fflush(stdout);
  2367. insil = 0;
  2368. silsegscnt = 0;
  2369. while(dz->samps_left > 0) {
  2370. if((exit_status = read_samps(ibuf,dz))<0) {
  2371. sprintf(errstr,"Failed to read data from sndfile.\n");
  2372. return(DATA_ERROR);
  2373. }
  2374. for(ibufpos=0;ibufpos<dz->ssampsread;ibufpos++) {
  2375. if(ibuf[ibufpos] == 0.0)
  2376. insil++;
  2377. else {
  2378. if(insil) {
  2379. if(insil >= dz->iparam[silpar]) {
  2380. silsegscnt++;
  2381. }
  2382. }
  2383. insil = 0;
  2384. }
  2385. }
  2386. }
  2387. if(insil)
  2388. silsegscnt++;
  2389. if(silsegscnt == 0) {
  2390. sprintf(errstr,"NO SILENCES FOUND IN FILE.\n");
  2391. return(MEMORY_ERROR);
  2392. }
  2393. silsegscnt++; /* in case less silences than sounds */
  2394. if((sndseekEx(dz->ifd[0],0,0)<0)){
  2395. sprintf(errstr,"sndseek() failed\n");
  2396. return SYSTEM_ERROR;
  2397. }
  2398. reset_filedata_counters(dz);
  2399. last_buf_start = 0;
  2400. /* STORE LOCATION OF STARTS AND ENDS OF SILENCE BLOCKS */
  2401. if((dz->lparray[arrayno] = (int *)malloc((silsegscnt * 2) * sizeof(int)))==NULL) {
  2402. sprintf(errstr,"INSUFFICIENT MEMORY TO STORE SILENCE LOCATIONS.\n");
  2403. return(MEMORY_ERROR);
  2404. }
  2405. silsegscnt = 0;
  2406. insil = 0;
  2407. silences = dz->lparray[arrayno];
  2408. fprintf(stdout,"INFO: Marking silence-separated Events.\n");
  2409. fflush(stdout);
  2410. while(dz->samps_left > 0) {
  2411. if((exit_status = read_samps(ibuf,dz))<0) {
  2412. sprintf(errstr,"Failed to read data from sndfile.\n");
  2413. return(DATA_ERROR);
  2414. }
  2415. for(ibufpos=0;ibufpos<dz->ssampsread;ibufpos++) {
  2416. if(ibuf[ibufpos] == 0.0) {
  2417. if(insil == 0)
  2418. silstart = last_buf_start + ibufpos;
  2419. insil++;
  2420. } else {
  2421. if(insil) {
  2422. if(insil >= dz->iparam[silpar]) {
  2423. silend = last_buf_start + ibufpos;
  2424. silences[silsegscnt++] = silstart;
  2425. silences[silsegscnt++] = silend;
  2426. }
  2427. }
  2428. insil = 0;
  2429. }
  2430. }
  2431. last_buf_start += dz->ssampsread;
  2432. }
  2433. if(silstart < 0) {
  2434. sprintf(errstr,"No signal found in sndfile.\n");
  2435. return(DATA_ERROR);
  2436. }
  2437. if(insil) { /* if silence at end */
  2438. silend = dz->insams[0];
  2439. silences[silsegscnt++] = silstart;
  2440. silences[silsegscnt++] = silend;
  2441. event_at_end = 0;
  2442. }
  2443. events = dz->lparray[arrayno]; /* we write over the original data store */
  2444. if(silences[0] == 0) { /* If first silence is at time zero */
  2445. for(k=1;k<silsegscnt;k++) /* map gaps between silences backwards into (=) events ( losing first silence in process) */
  2446. events[k-1] = silences[k]; /* --X--X-- to XX-XX- */
  2447. if(event_at_end) /* if last silence does not end at file end, it starts a final event */
  2448. events[silsegscnt-1] = dz->insams[0]; /* so add the end of file as end of final event, and silsegcnt stays same. --X--X-- thro XX-XX- to XX-XX-XX */
  2449. else /* otherwise final silent end, does NOT start a new event, so delete last entry */
  2450. silsegscnt -= 2; /* --X--X-- thro XX-XX- to XX-XX: subtract a start-end pair from count */
  2451. } else { /* first event at time zero */
  2452. for(k=silsegscnt;k>0;k--) /* map gaps between silences forwards into (=) events (eventually using extra address space assigned at end) */
  2453. events[k] = silences[k-1];
  2454. events[0] = 0; /* Add start of file as start of firsst event. --X--X-- to XX-XX-XX- */
  2455. if(event_at_end) { /* if last silence does not end at file end, it starts a final event */
  2456. events[silsegscnt+1] = dz->insams[0]; /* so add the end of file as end of final event */
  2457. silsegscnt += 2; /* --X--X-- thro XX-XX-XX- to XX-XX-XX-XX add a start-end pair to count */
  2458. } else {
  2459. /* last silence is at end of file, and does not start an event .... --X--X-- thro XX-XX-XX- to XX-XX-XX silsegscnt stays as is, last entry forgotten */
  2460. }
  2461. }
  2462. *eventsegscnt = silsegscnt;
  2463. fprintf(stdout,"INFO: Found %d events.\n",silsegscnt/2);
  2464. fflush(stdout);
  2465. return FINISHED;
  2466. }
  2467. /*************************** STEPSPREAD ****************************/
  2468. int stepspread(dataptr dz)
  2469. {
  2470. int exit_status, outchans = dz->iparam[0], n, m;
  2471. int eventsegscnt, buf_start, ibufpos, obufpos, eventstart, eventend;
  2472. int *events;
  2473. double *spreads, *levels;
  2474. float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1];
  2475. double time = 0.0, srate = (double)dz->infile->srate;
  2476. if((exit_status = count_events(5,0,&eventsegscnt,dz))<0)
  2477. return(exit_status);
  2478. events = dz->lparray[0];
  2479. for(n=1,m=2;n<eventsegscnt;n++,m+=2)
  2480. events[n] = events[m];
  2481. eventsegscnt /= 2; // We only need the starts of the events
  2482. if((dz->parray[0] = (double *)malloc(eventsegscnt * sizeof(double)))==NULL) {
  2483. sprintf(errstr,"INSUFFICIENT MEMORY TO STORE EVENT SPREAD VALS.\n");
  2484. return(MEMORY_ERROR);
  2485. }
  2486. if((dz->parray[1] = (double *)malloc(outchans * sizeof(double)))==NULL) {
  2487. sprintf(errstr,"INSUFFICIENT MEMORY TO STORE OUT-LEVELS.\n");
  2488. return(MEMORY_ERROR);
  2489. }
  2490. spreads = dz->parray[0];
  2491. levels = dz->parray[1];
  2492. if(dz->vflag[0]) {
  2493. m = 1;
  2494. for(n=0;n < eventsegscnt;n++) {
  2495. spreads[n] = min(m,dz->iparam[2]);
  2496. spreads[n] = min(spreads[n],outchans);
  2497. m+=2;
  2498. }
  2499. } else {
  2500. n = 0;
  2501. time = (double)(events[n])/srate;
  2502. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  2503. return(exit_status);
  2504. spreads[n++] = min(dz->param[2],outchans);
  2505. if(dz->brksize[2]) {
  2506. while(n < eventsegscnt) {
  2507. time = (double)(events[n])/srate;
  2508. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  2509. return(exit_status);
  2510. spreads[n] = min(dz->param[2],outchans);
  2511. n++;
  2512. }
  2513. } else {
  2514. while(n < eventsegscnt)
  2515. spreads[n++] = spreads[0];
  2516. }
  2517. }
  2518. fflush(stdout);
  2519. if((sndseekEx(dz->ifd[0],0,0)<0)){
  2520. sprintf(errstr,"sndseek() failed\n");
  2521. return SYSTEM_ERROR;
  2522. }
  2523. reset_filedata_counters(dz);
  2524. events[0] = 0; // We start at the start of the file
  2525. buf_start = 0;
  2526. if((exit_status = read_samps(ibuf,dz))<0) {
  2527. sprintf(errstr,"Failed to read data from sndfile.\n");
  2528. return(DATA_ERROR);
  2529. }
  2530. memset((char *)obuf,0,dz->buflen * outchans * sizeof(float));
  2531. ibufpos = 0;
  2532. obufpos = 0;
  2533. n = 1;
  2534. while(n <= eventsegscnt) {
  2535. eventstart = events[n-1] - buf_start;
  2536. if(n == eventsegscnt) {
  2537. eventend = dz->insams[0] - buf_start;
  2538. } else
  2539. eventend = events[n] - buf_start;
  2540. time = (double)eventstart/srate;
  2541. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  2542. return(exit_status);
  2543. dz->iparam[1] = (int)round(dz->param[1]) - 1; // centre is an integer numbered from 0 to N-1
  2544. dz->param[2] = spreads[n-1]; // precalcd
  2545. spread_set(dz);
  2546. while(ibufpos < eventstart) {
  2547. if(ibufpos >= dz->buflen) {
  2548. if((exit_status = write_samps(obuf,dz->buflen * outchans,dz))<0)
  2549. return(exit_status);
  2550. memset((char *)obuf,0,dz->buflen * outchans * sizeof(float));
  2551. buf_start += dz->buflen;
  2552. eventstart -= dz->buflen;
  2553. eventend -= dz->buflen;
  2554. ibufpos = 0;
  2555. obufpos = 0;
  2556. if((exit_status = read_samps(ibuf,dz))<0) {
  2557. sprintf(errstr,"Failed to read data from sndfile.\n");
  2558. return(DATA_ERROR);
  2559. }
  2560. }
  2561. for(m=0;m<outchans;m++)
  2562. obuf[obufpos + m] = (float)0.0;
  2563. ibufpos++;
  2564. obufpos += outchans;
  2565. }
  2566. while(ibufpos < eventend) {
  2567. if(ibufpos >= dz->buflen) {
  2568. if((exit_status = write_samps(obuf,dz->buflen * outchans,dz))<0)
  2569. return(exit_status);
  2570. memset((char *)obuf,0,dz->buflen * outchans * sizeof(float));
  2571. buf_start += dz->buflen;
  2572. eventend -= dz->buflen;
  2573. ibufpos = 0;
  2574. obufpos = 0;
  2575. if((exit_status = read_samps(ibuf,dz))<0) {
  2576. sprintf(errstr,"Failed to read data from sndfile.\n");
  2577. return(DATA_ERROR);
  2578. }
  2579. }
  2580. for(m=0;m<outchans;m++)
  2581. obuf[obufpos + m] = (float)(ibuf[ibufpos] * levels[m]);
  2582. ibufpos++;
  2583. obufpos += outchans;
  2584. }
  2585. n++;
  2586. }
  2587. if(ibufpos > 0) {
  2588. if((exit_status = write_samps(obuf,ibufpos * outchans,dz))<0)
  2589. return(exit_status);
  2590. }
  2591. return FINISHED;
  2592. }
  2593. /*************************** SPREAD_SET ****************************/
  2594. void spread_set(dataptr dz)
  2595. {
  2596. int outchans = dz->iparam[0];
  2597. int centre = dz->iparam[1];
  2598. double spread = dz->param[2];
  2599. double depth = min(dz->param[3],(double)outchans/2.0);
  2600. double rolloff = dz->param[4];
  2601. double *levels = dz->parray[1];
  2602. int stepped = dz->vflag[0];
  2603. int K, N, j, maxchan, minchan, chan, ochan;
  2604. double range, fraclevel, maxlevel, hole;
  2605. if(stepped)
  2606. depth = dz->iparam[3];
  2607. N = (int)floor(spread);
  2608. /* Initialise all levels to zero */
  2609. for(chan = 0;chan < outchans;chan++)
  2610. levels[chan] = 0.0;
  2611. /* Establish maxlevel (determined by rolloff) */
  2612. range = 1.0 - (1.0/(double)N);
  2613. maxlevel = 1.0 - (rolloff * range);
  2614. /* Do channels with full level first */
  2615. K = N/2;
  2616. if(EVEN(N))
  2617. K--;
  2618. minchan = centre - K;
  2619. maxchan = centre + K;
  2620. for(chan = minchan;chan <=maxchan;chan++) {
  2621. ochan = chan;
  2622. while(ochan < 0)
  2623. ochan += outchans;
  2624. while(ochan >= outchans)
  2625. ochan -= outchans;
  2626. levels[ochan] = maxlevel;
  2627. }
  2628. /* IF hole in middle */
  2629. if((hole = (spread/2.0) - depth) > 0) {
  2630. /* Zero channels in centre of hole */
  2631. K = (int)floor(hole);
  2632. for(j =0;j < K;j++) {
  2633. ochan = centre + j;
  2634. while(ochan >= outchans)
  2635. ochan -= outchans;
  2636. levels[ochan] = 0;
  2637. ochan = centre - j;
  2638. while(ochan < 0)
  2639. ochan += outchans;
  2640. levels[ochan] = 0;
  2641. }
  2642. /* Reduce levels adjacent to hole, if ness */
  2643. if(!stepped) {
  2644. fraclevel = hole - (double)K;
  2645. fraclevel = 1.0 - fraclevel;
  2646. fraclevel *= maxlevel;
  2647. ochan = centre + j;
  2648. while(ochan >= outchans)
  2649. ochan -= outchans;
  2650. levels[ochan] = fraclevel;
  2651. ochan = centre - j;
  2652. while(ochan < 0)
  2653. ochan += outchans;
  2654. levels[ochan] = fraclevel;
  2655. }
  2656. }
  2657. /* Finally, Do fractional channels on leading edge of spread */
  2658. if(stepped && (spread != outchans)) {
  2659. return;
  2660. }
  2661. fraclevel = (spread - (double)N);
  2662. if(ODD(N))
  2663. fraclevel = fraclevel/2.0;
  2664. else
  2665. fraclevel = (fraclevel + 1.0)/2.0;
  2666. fraclevel *= maxlevel;
  2667. maxchan++;
  2668. while(maxchan >= outchans)
  2669. maxchan -= outchans;
  2670. while(maxchan < 0)
  2671. maxchan += outchans;
  2672. minchan--;
  2673. while(minchan >= outchans)
  2674. minchan -= outchans;
  2675. while(minchan < 0)
  2676. minchan += outchans;
  2677. levels[maxchan] = (float)(levels[maxchan] + fraclevel);
  2678. levels[minchan] = (float)(levels[minchan] + fraclevel);
  2679. }
  2680. /*************************** PANSPREAD ****************************/
  2681. int panspread(dataptr dz)
  2682. {
  2683. int exit_status, outchans = dz->iparam[0], sectcnt, m, k;
  2684. int ibufpos, obufpos = 0;
  2685. double *levels;
  2686. int inchans = dz->infile->channels;
  2687. float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1];
  2688. double time = 0.0, srate = (double)dz->infile->srate;
  2689. int obuflen = (dz->buflen/inchans) * outchans;
  2690. double stereo_pos;
  2691. double centre=0.0;
  2692. int halfstage = outchans/2;
  2693. int c_left, c_rite;
  2694. double left_contrib_to_c_left, rite_contrib_to_c_left, left_contrib_to_c_rite, rite_contrib_to_c_rite, val;
  2695. if((dz->parray[0] = (double *)malloc(outchans * sizeof(double)))==NULL) {
  2696. sprintf(errstr,"INSUFFICIENT MEMORY TO STORE OUT-LEVELS.\n");
  2697. return(MEMORY_ERROR);
  2698. }
  2699. levels = dz->parray[0];
  2700. if((exit_status = read_samps(ibuf,dz))<0) {
  2701. sprintf(errstr,"Failed to read data from sndfile.\n");
  2702. return(DATA_ERROR);
  2703. }
  2704. memset((char *)obuf,0,obuflen * sizeof(float));
  2705. sectcnt = 0;
  2706. while(dz->ssampsread > 0) {
  2707. for(ibufpos = 0, obufpos = 0;ibufpos < dz->ssampsread;ibufpos+=inchans,obufpos += outchans) {
  2708. if(sectcnt % 256 == 0) {
  2709. time = (double)sectcnt/srate;
  2710. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  2711. return(exit_status);
  2712. spread_pan(&centre,dz);
  2713. }
  2714. if(dz->infile->channels == 2) {
  2715. c_left = (int)floor(centre);
  2716. c_rite = c_left + 1;
  2717. if(c_rite >= outchans)
  2718. c_rite -= outchans;
  2719. for(k=1;k<halfstage;k++) { // All loudpseakers to left of central pair get left signal
  2720. m = c_left - k;
  2721. if(m < 0)
  2722. m += outchans;
  2723. obuf[obufpos + m] = (float)(ibuf[ibufpos] * levels[m]);
  2724. }
  2725. for(k=1;k<halfstage;k++) { // All loudpseakers to right of central pair get right signal
  2726. m = c_rite + k;
  2727. if(m >= outchans)
  2728. m -= outchans;
  2729. obuf[obufpos + m] = (float)(ibuf[ibufpos+1] * levels[m]);
  2730. } // Central pair get a mix of left and right signals
  2731. stereo_pos = centre - (double)c_left;
  2732. left_contrib_to_c_left = (1.0 + (2.0 * stereo_pos))/2.0;
  2733. left_contrib_to_c_left = min(1.0,left_contrib_to_c_left);
  2734. rite_contrib_to_c_left = (1.0 - (2.0 * stereo_pos))/2.0;
  2735. rite_contrib_to_c_left = max(0.0,rite_contrib_to_c_left);
  2736. val = (ibuf[ibufpos] * left_contrib_to_c_left) + (ibuf[ibufpos+1] * rite_contrib_to_c_left);
  2737. val *= levels[c_left];
  2738. obuf[obufpos + c_left] = (float)val;
  2739. left_contrib_to_c_rite = ((2.0 * stereo_pos) - 1.0)/2.0;
  2740. left_contrib_to_c_rite = max(0.0,left_contrib_to_c_rite);
  2741. rite_contrib_to_c_rite = (3.0 - (2.0 * stereo_pos))/2.0;
  2742. rite_contrib_to_c_rite = min(1.0,rite_contrib_to_c_rite);
  2743. val = (ibuf[ibufpos] * left_contrib_to_c_rite) + (ibuf[ibufpos+1] * rite_contrib_to_c_rite);
  2744. val *= levels[c_rite];
  2745. obuf[obufpos + c_rite] = (float)val;
  2746. } else {
  2747. for(m=0;m<outchans;m++)
  2748. obuf[obufpos + m] = (float)(ibuf[ibufpos] * levels[m]);
  2749. }
  2750. sectcnt++;
  2751. }
  2752. if((exit_status = write_samps(obuf,obufpos,dz))<0)
  2753. return(exit_status);
  2754. memset((char *)obuf,0,obuflen * sizeof(float));
  2755. if((exit_status = read_samps(ibuf,dz))<0) {
  2756. sprintf(errstr,"Failed to read data from sndfile.\n");
  2757. return(DATA_ERROR);
  2758. }
  2759. }
  2760. if(obufpos > 0) {
  2761. if((exit_status = write_samps(obuf,obufpos,dz))<0)
  2762. return(exit_status);
  2763. }
  2764. return FINISHED;
  2765. }
  2766. /*
  2767. * left_contrib_to_c_left = * rite_contrib_to_c_left = * left_contrib_to_c_rite = * rite_contrib_to_c_rite =
  2768. * MAX of 1.0 AND * MIN of 0.0 AND * MAX of 0.0 AND * MAX of 1.0 AND
  2769. * (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;
  2770. * * * *
  2771. * POSITION OF CENTRE * POSITION OF CENTRE * POSITION OF CENTRE * POSITION OF CENTRE
  2772. * c-left c_rite * c-left c_rite * c-left c_rite * c-left c_rite
  2773. * 1.0 | . . . .________| * 1.0 |. . . . . . . . | * 1.0 | . . . . . . . .| * 1.0 |________ . . . |
  2774. * | / | * | | * | | * | \ |
  2775. * | / | * | | * | | * | \ |
  2776. * | / | * | | * | | * | \ |
  2777. * 0.5 |/ . . . . . . . | * 0.5 |. . . . . . . . | * 0.5 |. . . . . . . . | * 0.5 |. . . . . . . .\|
  2778. * | | * |\ | * | /| * | |
  2779. * | | * | \ | * | / | * | |
  2780. * | | * | \ | * | / | * | |
  2781. * 0.0 | . . . . . . . | * 0.0 | . . \_________| * 0.0 |_________/ . . | * 0.0 | . . . . . . . .|
  2782. *
  2783. */
  2784. /*************************** SPREAD_PAN ****************************/
  2785. void spread_pan(double *thiscentre,dataptr dz)
  2786. {
  2787. int outchans = dz->iparam[0];
  2788. double centre = dz->param[1];
  2789. double spread = min(dz->param[2],(double)outchans), halfspread = spread/2.0;
  2790. double depth = min(dz->param[3],(double)outchans/2.0);
  2791. double rolloff = dz->param[4];
  2792. double *levels = dz->parray[0];
  2793. double spredej_left, spredej_right;
  2794. int spredej_left_leftchan, spredej_right_leftchan, spredej_right_rightchan, k, j, ochan;
  2795. double range, maxlevel, hole, stereopos_left, stereopos_right, relpos, temp, holecompensate;
  2796. double holej_right, holej_left, zleft, zright, floor_zleft, floor_zright;
  2797. double left_leftchan_level, right_rightchan_level, spredej_left_rightchan;
  2798. double kk, jj, holing, mingap;
  2799. if(depth <= 0.0)
  2800. depth = FLTERR;
  2801. if((halfspread = spread/2.0) == 0.0)
  2802. halfspread = FLTERR;
  2803. if((centre = centre - 1.0) < 0.0)
  2804. centre += (double)outchans;
  2805. for(ochan = 0;ochan < outchans;ochan++)
  2806. levels[ochan] = 0.0;
  2807. /* Establish maxlevel (determined by rolloff) */
  2808. if(spread < 1.0)
  2809. range = 0.0;
  2810. else
  2811. range = 1.0 - (1.0/(double)spread);
  2812. maxlevel = 1.0 - (rolloff * range);
  2813. // Set all channels fully within the spread to maxlevel
  2814. spredej_left = centre - halfspread;
  2815. while(spredej_left < 0)
  2816. spredej_left += (double)outchans;
  2817. spredej_right = centre + halfspread;
  2818. while(spredej_right >= outchans)
  2819. spredej_right -= (double)outchans;
  2820. spredej_left_leftchan = (int)floor(spredej_left);
  2821. if((spredej_left_rightchan = spredej_left_leftchan + 1) >= outchans)
  2822. spredej_left_rightchan = 0;
  2823. spredej_right_leftchan = (int)floor(spredej_right);
  2824. hole = spread - (depth * 2.0);
  2825. if(spread >= outchans) {
  2826. for(k = 0;k<outchans; k++)
  2827. levels[k] = maxlevel;
  2828. if(hole <= 0.0)
  2829. return;
  2830. } else if(spread > 1.0) {
  2831. k = spredej_left_leftchan;
  2832. if(spredej_left_leftchan == spredej_left)
  2833. levels[k] = maxlevel;
  2834. if(++k >= outchans)
  2835. k -= outchans;
  2836. while(k != spredej_right_leftchan) {
  2837. levels[k] = maxlevel;
  2838. if(++k >= outchans)
  2839. k -= outchans;
  2840. }
  2841. levels[spredej_right_leftchan] = maxlevel;
  2842. } else {
  2843. /* Deal with case where spread extends to both sides of a channel, even if less than 1.0 */
  2844. zleft = centre - halfspread;
  2845. zright = centre + halfspread;
  2846. if(zleft < 0.0) {
  2847. zleft += outchans;
  2848. zright += outchans;
  2849. }
  2850. if(zleft >= 0.0)
  2851. floor_zleft = floor(zleft);
  2852. else
  2853. floor_zleft = -ceil(fabs(zleft));
  2854. if(zright >= 0.0)
  2855. floor_zright = floor(zright);
  2856. else
  2857. floor_zright = -ceil(fabs(zright));
  2858. if(floor_zleft < floor_zright)
  2859. levels[spredej_right_leftchan] = maxlevel;
  2860. }
  2861. /* Do fractional channels on leading edges of spread */
  2862. stereopos_left = spredej_left - (double)spredej_left_leftchan;
  2863. relpos = fabs(0.5 - stereopos_left) * 2.0; // position relative_to_stereo_centre : Range 0 - 1
  2864. temp = 1.0 + (relpos * relpos); // calculate stereo-hole-in-middle compensation
  2865. holecompensate = ROOT2 / sqrt(temp);
  2866. left_leftchan_level = (1 - stereopos_left) * maxlevel * holecompensate;
  2867. if(spredej_left_leftchan != spredej_right_leftchan)
  2868. levels[spredej_left_leftchan] = left_leftchan_level;
  2869. stereopos_right = spredej_right - (double)spredej_right_leftchan;
  2870. relpos = fabs(0.5 - stereopos_right) * 2.0; // position relative_to_stereo_centre : Range 0 - 1
  2871. temp = 1.0 + (relpos * relpos); // calculate stereo-hole-in-middle compensation
  2872. holecompensate = ROOT2 / sqrt(temp);
  2873. right_rightchan_level = stereopos_right * maxlevel * holecompensate;
  2874. if(spredej_right > spredej_right_leftchan) {
  2875. if((spredej_right_rightchan = spredej_right_leftchan + 1) >= outchans)
  2876. spredej_right_rightchan -= outchans;
  2877. if(spredej_right_rightchan != spredej_left_rightchan) {
  2878. if(spredej_right_rightchan == spredej_left_leftchan) {
  2879. levels[spredej_right_rightchan] += right_rightchan_level;
  2880. } else {
  2881. levels[spredej_right_rightchan] = right_rightchan_level;
  2882. }
  2883. }
  2884. }
  2885. /* IF hole in the middle of the spread, because depth too small, find edges of hole */
  2886. halfspread = spread/2.0;
  2887. if(hole > 0.0) {
  2888. holej_right = centre + halfspread - depth;
  2889. holej_left = centre - halfspread + depth;
  2890. k = (int)ceil(holej_left);
  2891. j = (int)floor(holej_right); // Look at all chans in hole
  2892. while(k <= j) {
  2893. kk = k - holej_left;
  2894. jj = holej_right - k;
  2895. mingap = min(jj,kk);
  2896. holing = min(mingap,1.0);
  2897. holing = 1.0 - holing;
  2898. ochan = k;
  2899. while(ochan < 0)
  2900. ochan += outchans;
  2901. while(ochan >= outchans)
  2902. ochan -= outchans;
  2903. levels[ochan] *= holing;
  2904. k++;
  2905. }
  2906. }
  2907. *thiscentre = centre;
  2908. /* !!!!!!!!!!!!! */
  2909. }
  2910. /*
  2911. * INNER HOLE
  2912. * 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;
  2913. * mingap = minimum distance from holeedge to nearest channel
  2914. * 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;
  2915. * 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
  2916. * this_level = 1.0 - (range * holeratio); When holeratio = 1, level becomes 1.0 - range = this_level i.e. expected stereo level
  2917. * = 1.0 - (1.0 - this_level) = this_level i.e. expected stereo level
  2918. */
  2919. /*************************** READ_ANTIPHON_DATA ****************************/
  2920. int read_antiphon_data(char *str,dataptr dz)
  2921. {
  2922. int exit_status;
  2923. dz->all_words = 0;
  2924. if((exit_status = store_filename(str,dz))<0)
  2925. return(exit_status);
  2926. return FINISHED;
  2927. }
  2928. /*************************** CHECK_ANTIPHON_DATA ****************************/
  2929. int setup_antiphon_arrays(char *str,dataptr dz)
  2930. {
  2931. char *p, *q, *antiphon0, *antiphon1 = NULL;
  2932. int got_separator = 0, maxchan = 0, strcnt, j, n, k;
  2933. int inchans = dz->infile->channels;
  2934. int outchans = dz->iparam[0], distribution;
  2935. int *antiphon_a, *antiphon_b;
  2936. antiphon0 = str;
  2937. p = str;
  2938. /*
  2939. * Expects astring like 'abc-def'
  2940. * Looks for the separator '-' and replaces it be ENDOFSTR
  2941. * splittingbthe source string into 2 i.e. abc & def
  2942. * These then become antiphon0 and antiphon1
  2943. */
  2944. while (*p != ENDOFSTR) {
  2945. if(*p == '-') {
  2946. got_separator = 1;
  2947. if(p-str == 0) {
  2948. sprintf(errstr,"Invalid Antiphon Data : no channels before separator\n");
  2949. return(DATA_ERROR);
  2950. }
  2951. antiphon1 = p+1;
  2952. if(*antiphon1 == ENDOFSTR) {
  2953. sprintf(errstr,"Invalid Antiphon Data : no channels after separator\n");
  2954. return(DATA_ERROR);
  2955. }
  2956. *p = ENDOFSTR;
  2957. } else if(!isalpha(*p)) {
  2958. sprintf(errstr,"Invalid Antiphon Data : invalid character (%c)\n",*p);
  2959. return(DATA_ERROR);
  2960. }
  2961. p++;
  2962. }
  2963. if(!got_separator) {
  2964. sprintf(errstr,"Invalid Antiphon Data : no separator character (-)\n");
  2965. return(DATA_ERROR);
  2966. }
  2967. p = antiphon0;
  2968. /*
  2969. * Check for character duplication (not allowed)
  2970. * in antiphon0 and antiphon1
  2971. */
  2972. while(*p != ENDOFSTR) {
  2973. q = p + 1;
  2974. if(*q == ENDOFSTR)
  2975. break;
  2976. while(*q != ENDOFSTR) {
  2977. if(*p == *q) {
  2978. sprintf(errstr,"Invalid Antiphon Data : repeated channel (%c)\n",*p);
  2979. return(DATA_ERROR);
  2980. }
  2981. q++;
  2982. }
  2983. p++;
  2984. }
  2985. p = antiphon1;
  2986. while(*p != ENDOFSTR) {
  2987. q = p + 1;
  2988. if(*q == ENDOFSTR)
  2989. break;
  2990. while(*q != ENDOFSTR) {
  2991. if(*p == *q) {
  2992. sprintf(errstr,"Invalid Antiphon Data : repeated channel (%c)\n",*p);
  2993. return(DATA_ERROR);
  2994. }
  2995. q++;
  2996. }
  2997. p++;
  2998. }
  2999. p = antiphon0;
  3000. strcnt = 0;
  3001. /*
  3002. * Find the maximum channel referred to in "antiphon0-ENDOFSTR-antiphon1-ENDOFSTR"
  3003. * Counts the ENDOFSTR markers, existing at the 2nd.
  3004. */
  3005. while(strcnt < 2) {
  3006. switch(*p) {
  3007. case('a'): maxchan = max(1,maxchan); break;
  3008. case('b'): maxchan = max(2,maxchan); break;
  3009. case('c'): maxchan = max(3,maxchan); break;
  3010. case('d'): maxchan = max(4,maxchan); break;
  3011. case('e'): maxchan = max(5,maxchan); break;
  3012. case('f'): maxchan = max(6,maxchan); break;
  3013. case('g'): maxchan = max(7,maxchan); break;
  3014. case('h'): maxchan = max(8,maxchan); break;
  3015. case('i'): maxchan = max(9,maxchan); break;
  3016. case('j'): maxchan = max(10,maxchan); break;
  3017. case('k'): maxchan = max(11,maxchan); break;
  3018. case('l'): maxchan = max(12,maxchan); break;
  3019. case('m'): maxchan = max(13,maxchan); break;
  3020. case('n'): maxchan = max(14,maxchan); break;
  3021. case('o'): maxchan = max(15,maxchan); break;
  3022. case('p'): maxchan = max(16,maxchan); break;
  3023. case(ENDOFSTR):
  3024. strcnt++;
  3025. break;
  3026. default:
  3027. sprintf(errstr,"Invalid Antiphon Character: (a-p, lower case, only)\n");
  3028. return(DATA_ERROR);
  3029. }
  3030. p++;
  3031. }
  3032. if(maxchan > outchans) {
  3033. sprintf(errstr,"Maximum channel in antiphon data (%d) incompatible with outchannel count (%d)\n",maxchan,outchans);
  3034. return(DATA_ERROR);
  3035. }
  3036. /*
  3037. * Finds length of each antiphon string.
  3038. */
  3039. dz->antiphlen0 = strlen(antiphon0);
  3040. dz->antiphlen1 = strlen(antiphon1);
  3041. /*
  3042. * If more than 1 channel in input (say N), and K output channels
  3043. * Checks that K = N or 2N or 3N etc
  3044. * (i.e. integral number of output channels per input channel)
  3045. */
  3046. if(inchans > 1) {
  3047. if((dz->antiphlen0/inchans) * inchans != dz->antiphlen0) {
  3048. sprintf(errstr,"1st antiphon channel count not an integral multiple of inchans (%d).\n",inchans);
  3049. return(DATA_ERROR);
  3050. }
  3051. if((dz->antiphlen1/inchans) * inchans != dz->antiphlen1) {
  3052. sprintf(errstr,"2nd antiphon channel count not an integral multiple of inchans (%d).\n",inchans);
  3053. return(DATA_ERROR);
  3054. }
  3055. }
  3056. /*
  3057. * Generates storage for the real antiphon arrays, TWICE as long as the antiphon strings.
  3058. * These will store the end and start of each antiphon event (therefore 2 er event)
  3059. */
  3060. if((dz->lparray[0] = (int *)malloc((dz->antiphlen0 * 2) * sizeof(int)))==NULL) {
  3061. sprintf(errstr,"Insufficient memory for 1st antiphon data.\n");
  3062. return(DATA_ERROR);
  3063. }
  3064. if((dz->lparray[1] = (int *)malloc((dz->antiphlen1 * 2) * sizeof(int)))==NULL) {
  3065. sprintf(errstr,"Insufficient memory for 2nd antiphon data.\n");
  3066. return(DATA_ERROR);
  3067. }
  3068. antiphon_a = dz->lparray[0];
  3069. antiphon_b = dz->lparray[1];
  3070. /*
  3071. * For N input channels, and K output chans,
  3072. * each inchan is distributed to K/N output channels.
  3073. * (K/N is an integer: checked above)
  3074. */
  3075. distribution = dz->antiphlen0/inchans;
  3076. j = 0;
  3077. /*
  3078. * Associate each inchannel
  3079. * with K/N output channels of antiphon0
  3080. */
  3081. p = antiphon0;
  3082. for(n=0;n<inchans;n++) {
  3083. for(k=0;k < distribution;k++) {
  3084. antiphon_a[j++] = n;
  3085. antiphon_a[j++] = *p - ASCTOINT;
  3086. p++;
  3087. }
  3088. }
  3089. /*
  3090. * Similar operation for antiphon1
  3091. */
  3092. distribution = dz->antiphlen1/inchans;
  3093. j = 0;
  3094. p = antiphon1;
  3095. for(n=0;n<inchans;n++) {
  3096. for(k=0;k < distribution;k++) {
  3097. antiphon_b[j++] = n;
  3098. antiphon_b[j++] = *p - ASCTOINT;
  3099. p++;
  3100. }
  3101. }
  3102. return FINISHED;
  3103. }
  3104. /*************************** GENERATE_ANTIPHONAL_EVENTS_ARRAY ****************************/
  3105. int generate_antiphonal_events_array(dataptr dz)
  3106. {
  3107. int exit_status, inchans = dz->infile->channels;
  3108. int maxsamps = dz->insams[0], n, cnt, sampcnt, eventscnt, start;
  3109. double maxdur, time, srate = (double)dz->infile->srate;
  3110. int *events;
  3111. int splicelen = (int)round(dz->param[3] * MS_TO_SECS * srate) * inchans;
  3112. if(dz->infilecnt > 1) {
  3113. for(n=1;n<dz->infilecnt;n++)
  3114. maxsamps = max(maxsamps,dz->insams[n]);
  3115. }
  3116. maxdur = (double)(maxsamps/inchans)/srate;
  3117. /* Count how many antiphonal 'events' there will be */
  3118. if(dz->brksize[1]) { // eventdur
  3119. time = 0.0;
  3120. cnt = 0;
  3121. while(time < maxdur) {
  3122. cnt++;
  3123. if((exit_status = read_value_from_brktable(time,1,dz))<0)
  3124. return(exit_status);
  3125. time += dz->param[1];
  3126. }
  3127. } else {
  3128. cnt = (int)floor(maxdur/dz->param[1]);
  3129. }
  3130. if((dz->lparray[2] = (int *)malloc(cnt * 2 * sizeof(int))) == NULL) {
  3131. sprintf(errstr,"Insufficient memory for events array.\n");
  3132. return MEMORY_ERROR;
  3133. }
  3134. events = dz->lparray[2];
  3135. /* Store timing of every antiphonal 'event' end+startofnext (i.e. bbccdd) */
  3136. time = 0.0;
  3137. cnt = 0;
  3138. while(time < maxdur) {
  3139. if(dz->brksize[1]) {
  3140. if((exit_status = read_value_from_brktable(time,1,dz))<0)
  3141. return(exit_status);
  3142. }
  3143. time += dz->param[1];
  3144. if(time < maxdur) {
  3145. sampcnt = (int)round(time * srate) * inchans;
  3146. events[cnt++] = sampcnt;
  3147. events[cnt++] = sampcnt;
  3148. }
  3149. }
  3150. eventscnt = cnt;
  3151. cnt = 0;
  3152. if(dz->brksize[2] == 0)
  3153. dz->iparam[2] = (int)round(dz->param[2] * srate) * inchans;
  3154. while(cnt < eventscnt) { // eventgaps
  3155. time = (double)(events[cnt]/inchans)/srate;
  3156. if(dz->brksize[2]) {
  3157. if((exit_status = read_value_from_brktable(time,2,dz))<0)
  3158. return(exit_status);
  3159. dz->iparam[2] = (int)round(dz->param[2] * srate) * inchans;
  3160. }
  3161. events[cnt] -= dz->iparam[2]; // subtract gap value from event end
  3162. cnt += 2;
  3163. }
  3164. start = 0;
  3165. cnt = 0;
  3166. while(cnt < eventscnt) { // check no events too short
  3167. if(events[cnt++] - start <= splicelen) {
  3168. sprintf(errstr,"Events too short for splices at %lf\n",(double)(start/inchans)/srate);
  3169. return(DATA_ERROR);
  3170. }
  3171. start = events[cnt++];
  3172. }
  3173. dz->antievents = eventscnt;
  3174. return FINISHED;
  3175. }
  3176. /*************************** ANTIPHONAL_EVENTS ****************************/
  3177. int antiphonal_events(dataptr dz)
  3178. {
  3179. int exit_status;
  3180. int inchans = dz->infile->channels, outchans = dz->iparam[0], arrayno, ichan, ochan;
  3181. int obuflen = (dz->buflen/inchans) * outchans, silsegscnt, buf_start;
  3182. int segscnt, segstart, segend, arraysize, outwrite, ibufpos, obufpos = 0, abs_samp_pos;
  3183. int *events, *array, k, j, grpcnt;
  3184. float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1];
  3185. if((exit_status = count_events(1,2,&silsegscnt,dz))<0)
  3186. return(exit_status);
  3187. events = dz->lparray[2];
  3188. if(dz->infile->channels > 1) {
  3189. for(k = 0,j = 1;k < silsegscnt; k+=2,j+=2) {
  3190. events[k] = (events[k]/inchans) * inchans; // Event start rounded down to chan-group boundary (if ness)
  3191. if((grpcnt = events[j]/inchans) * inchans != events[j]) {
  3192. grpcnt++; // Event end rounded up to chan-group boundary (if ness)
  3193. events[j] = grpcnt * inchans;
  3194. }
  3195. }
  3196. }
  3197. k = silsegscnt/2;
  3198. if(k < 2) {
  3199. sprintf(errstr,"Only one event found. No panning will take place. Try adjusting the length of silences you are using.\n");
  3200. return(DATA_ERROR);
  3201. } else {
  3202. fprintf(stdout,"INFO: %d distinct events found.\n",k);
  3203. fflush(stdout);
  3204. }
  3205. /* PAN, SWITCHING ANTIPHONALLY FOR EACH PEAK */
  3206. fprintf(stdout,"INFO: Panning sound.\n");
  3207. fflush(stdout);
  3208. if((sndseekEx(dz->ifd[0],0,0)<0)){
  3209. sprintf(errstr,"sndseek() failed\n");
  3210. return SYSTEM_ERROR;
  3211. }
  3212. reset_filedata_counters(dz);
  3213. buf_start = 0;
  3214. segscnt = 0;
  3215. segstart = events[segscnt++];
  3216. segend = events[segscnt++];
  3217. arrayno = 0;
  3218. array = dz->lparray[0];
  3219. arraysize = dz->antiphlen0;
  3220. while(dz->samps_left) {
  3221. while(dz->total_samps_read <= segstart) {
  3222. outwrite = (dz->ssampsread/inchans) * outchans;
  3223. if((exit_status = write_samps(obuf,outwrite,dz))<0)
  3224. return(exit_status);
  3225. memset((char *)obuf,0,obuflen * sizeof(float));
  3226. buf_start = dz->total_samps_read;
  3227. if((exit_status = read_samps(ibuf,dz))<0) {
  3228. sprintf(errstr,"Failed to read data from sndfile.\n");
  3229. return(DATA_ERROR);
  3230. }
  3231. }
  3232. ibufpos = segstart - buf_start;
  3233. abs_samp_pos = segstart;
  3234. while(abs_samp_pos < segend) {
  3235. obufpos = (ibufpos/inchans) * outchans;
  3236. for(ichan = 0,ochan = 1; ichan < arraysize;ichan+=2, ochan+= 2)
  3237. obuf[obufpos + array[ochan]] = (float)(obuf[obufpos + array[ochan]] + ibuf[ibufpos + array[ichan]]); // out chan ochan gets in chan ichan added in
  3238. ibufpos += inchans;
  3239. obufpos += outchans;
  3240. abs_samp_pos += inchans;
  3241. if(ibufpos >= dz->ssampsread) {
  3242. outwrite = (dz->ssampsread/inchans) * outchans;
  3243. if((exit_status = write_samps(obuf,outwrite,dz))<0)
  3244. return(exit_status);
  3245. memset((char *)obuf,0,obuflen * sizeof(float));
  3246. buf_start = dz->total_samps_read;
  3247. if((exit_status = read_samps(ibuf,dz))<0) {
  3248. sprintf(errstr,"Failed to read data from sndfile.\n");
  3249. return(DATA_ERROR);
  3250. }
  3251. ibufpos = 0;
  3252. obufpos = 0;
  3253. }
  3254. }
  3255. if(segscnt >= silsegscnt)
  3256. break;
  3257. if(arrayno == 0) {
  3258. arrayno = 1;
  3259. array = dz->lparray[1];
  3260. arraysize = dz->antiphlen1;
  3261. } else {
  3262. arrayno = 0;
  3263. array = dz->lparray[0];
  3264. arraysize = dz->antiphlen0;
  3265. }
  3266. segstart = events[segscnt++];
  3267. segend = events[segscnt++];
  3268. }
  3269. if(obufpos > 0) {
  3270. if((exit_status = write_samps(obuf,obufpos,dz))<0)
  3271. return(exit_status);
  3272. }
  3273. return(FINISHED);
  3274. }
  3275. /*************************** ANTIPHONY ****************************/
  3276. int antiphony(dataptr dz)
  3277. {
  3278. int exit_status;
  3279. double srate = (double)dz->infile->srate;
  3280. int inchans = dz->infile->channels, outchans = dz->iparam[0], antiphonstate, thisfile, nextfile;
  3281. int splicelen = (int)round(dz->param[3] * MS_TO_SECS * srate) * inchans; // splice length is measured in input-file frame
  3282. int obuflen = (dz->buflen/inchans) * outchans, n, samps_read;
  3283. int *events = dz->lparray[2], *array0, *array1, arraysize0, arraysize1;
  3284. float *obuf = dz->sampbuf[dz->infilecnt], *ibuf1, *ibuf2;
  3285. int abs_samp_pos, ibufpos, obufpos, cnt;
  3286. int lasteventend, lasteventdnsplicend, thisevent, upsplicend, ichan, ochan, outwrite;
  3287. double dnsplicval, upsplicval, splicincr;
  3288. int totalsamps_to_process;
  3289. splicincr = 1.0/(double)(splicelen/inchans);
  3290. totalsamps_to_process = 0;
  3291. dz->ssampsread = 0;
  3292. for(n=0;n< dz->infilecnt;n++) {
  3293. memset(dz->sampbuf[n],0,dz->buflen * sizeof(float)); // If nothing is read, because data in this file is finished, buffer will have zeros zeros
  3294. if((samps_read = fgetfbufEx(dz->sampbuf[n],dz->buflen,dz->ifd[n],0)) < 0) {
  3295. sprintf(errstr,"Sound read error.\n");
  3296. return(SYSTEM_ERROR);
  3297. }
  3298. if(samps_read > dz->ssampsread)
  3299. dz->ssampsread = samps_read;
  3300. if(dz->insams[n] > totalsamps_to_process)
  3301. totalsamps_to_process = dz->insams[n];
  3302. }
  3303. memset(obuf,0,obuflen * sizeof(float));
  3304. antiphonstate = 0; // Establish 1st 2 antiphon states (need both, as antiphons may overlap during crossfade).
  3305. array0 = dz->lparray[0];
  3306. arraysize0 = dz->antiphlen0;
  3307. array1 = dz->lparray[1];
  3308. arraysize1 = dz->antiphlen1;
  3309. thisfile = 0; // Establish 1st 2 files to use (need both, if infilecnt > 1, as antiphons may overlap during crossfade).
  3310. ibuf1 = dz->sampbuf[thisfile];
  3311. nextfile = (thisfile + 1) % dz->infilecnt;
  3312. ibuf2 = dz->sampbuf[nextfile];
  3313. abs_samp_pos = 0;
  3314. ibufpos = 0;
  3315. obufpos = 0;
  3316. cnt = 0;
  3317. lasteventend = events[cnt++];
  3318. lasteventdnsplicend = lasteventend + splicelen;
  3319. thisevent = events[cnt++];
  3320. while(cnt < dz->antievents) {
  3321. upsplicend = thisevent + splicelen; // abs samps end of upslice in infile(s)
  3322. while(abs_samp_pos < lasteventend) {
  3323. for(ichan = 0,ochan = 1; ichan < arraysize0;ichan+=2, ochan+= 2)
  3324. obuf[obufpos + array0[ochan]] = (float)(obuf[obufpos + array0[ochan]] + ibuf1[ibufpos + array0[ichan]]); // oout chan ochan gets in chan ichan added in
  3325. ibufpos += inchans;
  3326. obufpos += outchans;
  3327. abs_samp_pos += inchans;
  3328. if(ibufpos >= dz->ssampsread) {
  3329. outwrite = (dz->ssampsread/inchans) * outchans;
  3330. if((exit_status = write_samps(obuf,outwrite,dz))<0)
  3331. return(exit_status);
  3332. memset((char *)obuf,0,obuflen * sizeof(float));
  3333. dz->ssampsread = 0;
  3334. for(n=0;n< dz->infilecnt;n++) {
  3335. memset(dz->sampbuf[n],0,dz->buflen * sizeof(float));
  3336. if((samps_read = fgetfbufEx(dz->sampbuf[n],dz->buflen,dz->ifd[n],0)) < 0) {
  3337. sprintf(errstr,"Sound read error.\n");
  3338. return(SYSTEM_ERROR);
  3339. } // If nothing is read, because data in this file is finished, buffer is still full of zeros
  3340. if(samps_read > dz->ssampsread)
  3341. dz->ssampsread = samps_read; // Continue until longest file is empty
  3342. }
  3343. if(dz->ssampsread == 0) {
  3344. fprintf(stdout,"WARNING: Termination before all events executed.\n");
  3345. fflush(stdout);
  3346. break;
  3347. }
  3348. ibufpos = 0;
  3349. obufpos = 0;
  3350. }
  3351. }
  3352. dnsplicval = 1.0;
  3353. upsplicval = 0.0;
  3354. while(abs_samp_pos < upsplicend) {
  3355. if(abs_samp_pos < lasteventdnsplicend) {
  3356. dnsplicval = max(0.0,dnsplicval - splicincr);
  3357. for(ichan = 0,ochan = 1; ichan < arraysize0;ichan+=2, ochan+= 2)
  3358. obuf[obufpos + array0[ochan]] = (float)(obuf[obufpos + array0[ochan]] + ibuf1[ibufpos + array0[ichan]] * dnsplicval);
  3359. }
  3360. if(abs_samp_pos >= thisevent) {
  3361. upsplicval = min(1.0,upsplicval + splicincr);
  3362. for(ichan = 0,ochan = 1; ichan < arraysize1;ichan+=2, ochan+= 2)
  3363. obuf[obufpos + array1[ochan]] = (float)(obuf[obufpos + array1[ochan]] + ibuf2[ibufpos + array1[ichan]] * upsplicval);
  3364. }
  3365. ibufpos += inchans;
  3366. obufpos += outchans;
  3367. abs_samp_pos += inchans;
  3368. if(ibufpos >= dz->ssampsread) {
  3369. outwrite = (dz->ssampsread/inchans) * outchans;
  3370. if((exit_status = write_samps(obuf,outwrite,dz))<0)
  3371. return(exit_status);
  3372. memset((char *)obuf,0,obuflen * sizeof(float));
  3373. dz->ssampsread = 0;
  3374. for(n=0;n< dz->infilecnt;n++) {
  3375. memset(dz->sampbuf[n],0,dz->buflen * sizeof(float));
  3376. if((samps_read = fgetfbufEx(dz->sampbuf[n],dz->buflen,dz->ifd[n],0)) < 0) {
  3377. sprintf(errstr,"Sound read error.\n");
  3378. return(SYSTEM_ERROR);
  3379. } // If nothing is read, because data in this file is finished, buffer is still full of zeros
  3380. if(samps_read > dz->ssampsread)
  3381. dz->ssampsread = samps_read;
  3382. }
  3383. if(dz->ssampsread == 0) {
  3384. fprintf(stdout,"WARNING: Termination before all events executed.\n");
  3385. fflush(stdout);
  3386. break;
  3387. }
  3388. ibufpos = 0;
  3389. obufpos = 0;
  3390. }
  3391. }
  3392. if(antiphonstate == 0) { // swap antiphon arrays
  3393. array0 = dz->lparray[1];
  3394. arraysize0 = dz->antiphlen1;
  3395. array1 = dz->lparray[0];
  3396. arraysize1 = dz->antiphlen0;
  3397. antiphonstate = 1;
  3398. } else {
  3399. array0 = dz->lparray[0];
  3400. arraysize0 = dz->antiphlen0;
  3401. array1 = dz->lparray[1];
  3402. arraysize1 = dz->antiphlen1;
  3403. antiphonstate = 0;
  3404. }
  3405. thisfile = nextfile; // move to next infile, if more than one
  3406. ibuf1 = dz->sampbuf[thisfile];
  3407. nextfile = (thisfile + 1) % dz->infilecnt;
  3408. ibuf2 = dz->sampbuf[nextfile];
  3409. lasteventend = events[cnt++]; // abs sampcnt end of lastevent in infile(s)
  3410. lasteventdnsplicend = lasteventend + splicelen; // abs sampcnt end of splice on end of lastevent in infile(s)
  3411. thisevent = events[cnt++];
  3412. }
  3413. lasteventend = totalsamps_to_process;
  3414. while(abs_samp_pos < lasteventend) { // Do end of last event
  3415. for(ichan = 0,ochan = 1; ichan < arraysize0;ichan+=2, ochan+= 2)
  3416. obuf[obufpos + array0[ochan]] = (float)(obuf[obufpos + array0[ochan]] + ibuf1[ibufpos + array0[ichan]]); // oout chan ochan gets in chan ichan added in
  3417. ibufpos += inchans;
  3418. obufpos += outchans;
  3419. abs_samp_pos += inchans;
  3420. if(ibufpos >= dz->ssampsread) {
  3421. outwrite = (dz->ssampsread/inchans) * outchans;
  3422. if((exit_status = write_samps(obuf,outwrite,dz))<0)
  3423. return(exit_status);
  3424. memset((char *)obuf,0,obuflen * sizeof(float));
  3425. dz->ssampsread = 0;
  3426. for(n=0;n< dz->infilecnt;n++) {
  3427. memset(dz->sampbuf[n],0,dz->buflen * sizeof(float));
  3428. if((samps_read = fgetfbufEx(dz->sampbuf[n],dz->buflen,dz->ifd[n],0)) < 0) {
  3429. sprintf(errstr,"Sound read error.\n");
  3430. return(SYSTEM_ERROR);
  3431. } // If nothing is read, because data in this file is finished, buffer is still full of zeros
  3432. if(samps_read > dz->ssampsread)
  3433. dz->ssampsread = samps_read; // Continue until longest file is empty
  3434. }
  3435. if(dz->ssampsread == 0) {
  3436. fprintf(stdout,"WARNING: Possible termination before all events executed.\n");
  3437. fflush(stdout);
  3438. break;
  3439. }
  3440. ibufpos = 0;
  3441. obufpos = 0;
  3442. }
  3443. }
  3444. if(obufpos > 0) {
  3445. if((exit_status = write_samps(obuf,obufpos,dz))<0)
  3446. return(exit_status);
  3447. }
  3448. return(FINISHED);
  3449. }
  3450. /*************************** CROSSPAN ****************************/
  3451. int crosspan(dataptr dz)
  3452. {
  3453. int exit_status, chans = dz->infile->channels, n, m, typ = -1;
  3454. int bufpos, eventcnt, lasteventcnt, abs_samp_cnt, thisevent, nextevent, lastmapcnt, mapcnt;
  3455. int timestep;
  3456. double timefrac, span, chandiv = 1.0/(double)chans, rolloff = dz->param[0], centrelevel;
  3457. float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1];
  3458. int *events = dz->lparray[0], *maps = dz->lparray[1], *map, *thismap, *nextmap;
  3459. if((exit_status = read_samps(ibuf,dz))<0) {
  3460. sprintf(errstr,"Failed to read data from sndfile.\n");
  3461. return(DATA_ERROR);
  3462. }
  3463. memset((char *)obuf,0,dz->buflen * sizeof(float));
  3464. fprintf(stdout,"INFO: Panning the sound\n");
  3465. fflush(stdout);
  3466. centrelevel = (1.0 - chandiv) * (1.0 - rolloff);
  3467. centrelevel += chandiv;
  3468. bufpos = 0;
  3469. abs_samp_cnt = 0;
  3470. lasteventcnt = 0;
  3471. eventcnt = 1;
  3472. lastmapcnt = 0;
  3473. mapcnt = chans;
  3474. while(eventcnt < dz->itemcnt) {
  3475. thisevent = events[lasteventcnt];
  3476. nextevent = events[eventcnt];
  3477. thismap = maps + lastmapcnt;
  3478. nextmap = maps + mapcnt;
  3479. timestep = nextevent - thisevent;
  3480. if(thismap[0] < 0) {
  3481. if(nextmap[0] < 0)
  3482. typ = ATCENTRE; // Both maps put all data at centre
  3483. else
  3484. typ = FROMCENTRE; // Moves from centre to edge
  3485. } else {
  3486. if(nextmap[0] < 0)
  3487. typ = TOCENTRE; // Moves from edge to centre
  3488. else {
  3489. for(n=0;n<chans;n++) {
  3490. if(thismap[n] != nextmap[n]) {
  3491. typ = CROSSCENTRE; // Moves from edge, thro centre, to edge
  3492. break;
  3493. }
  3494. }
  3495. if(n == chans)
  3496. typ = ATEDGE; // At edge, and does not move
  3497. }
  3498. }
  3499. while(abs_samp_cnt < nextevent) {
  3500. if(bufpos >= dz->ssampsread) {
  3501. if((exit_status = write_samps(obuf,dz->ssampsread,dz))<0)
  3502. return(exit_status);
  3503. memset((char *)obuf,0,dz->buflen * sizeof(float));
  3504. dz->ssampsread = 0;
  3505. if((exit_status = read_samps(ibuf,dz))<0) {
  3506. sprintf(errstr,"Failed to read data from sndfile.\n");
  3507. return(DATA_ERROR);
  3508. }
  3509. if(dz->ssampsread == 0)
  3510. break;
  3511. bufpos = 0;
  3512. }
  3513. timefrac = (double)(abs_samp_cnt - thisevent)/(double)timestep;
  3514. switch(typ) {
  3515. case(ATCENTRE): // Both maps put all data at centre
  3516. for(n=0;n<chans;n++) { // Ordering of channels is irrelevant,
  3517. for(m=0;m<chans;m++) // as all inchans go to all outchans
  3518. obuf[bufpos+n] = (float)(obuf[bufpos+n] + ibuf[bufpos+m]);
  3519. obuf[bufpos+n] = (float)(obuf[bufpos+n] * centrelevel);
  3520. }
  3521. break;
  3522. case(FROMCENTRE):
  3523. span = 1.0 - timefrac;
  3524. map = nextmap;
  3525. do_span(map,span,ibuf,obuf,bufpos,rolloff,chans);
  3526. break;
  3527. case(TOCENTRE):
  3528. span = timefrac;
  3529. map = thismap;
  3530. do_span(map,span,ibuf,obuf,bufpos,rolloff,chans);
  3531. break;
  3532. case(CROSSCENTRE):
  3533. if(timefrac <= 0.5) { // Moves to centre
  3534. map = thismap;
  3535. span = timefrac * 2.0;
  3536. } else { // Then away from centre
  3537. map = nextmap;
  3538. span = (1.0 - timefrac) * 2.0;
  3539. }
  3540. do_span(map,span,ibuf,obuf,bufpos,rolloff,chans);
  3541. break;
  3542. case(ATEDGE): // Mapping not changing.
  3543. for(n=0;n<chans;n++) // Each outchan mapped from single inchan.
  3544. obuf[bufpos+n] = ibuf[bufpos+thismap[n]];
  3545. break; // No levelscaling required.
  3546. default:
  3547. sprintf(errstr,"Bug: Panning type not assigned.\n");
  3548. return(PROGRAM_ERROR);
  3549. }
  3550. bufpos += chans;
  3551. abs_samp_cnt += chans;
  3552. }
  3553. lasteventcnt = eventcnt;
  3554. eventcnt++;
  3555. lastmapcnt += chans;
  3556. mapcnt += chans;
  3557. }
  3558. if(bufpos > 0) {
  3559. if((exit_status = write_samps(obuf,bufpos,dz))<0)
  3560. return(exit_status);
  3561. }
  3562. return(FINISHED);
  3563. }
  3564. /*************************** DO_SPAN ****************************/
  3565. void do_span(int *map,double span,float *ibuf,float *obuf,int bufpos,double rolloff,int chans)
  3566. {
  3567. int n, m, outchan;
  3568. double chanspan = span * (double)chans; // number of channels spanned
  3569. double halfspan = chanspan/2.0; // half the number of channels spanned
  3570. double maxchan, minchan;
  3571. int maxfullchan, minfullchan, trumaxfullchan, truminfullchan, truchan;
  3572. double partial_level; // level scaling on any channel only partially spanned
  3573. double sidelevel; // level of adjacent-to-centre chans when chanspan < 1
  3574. double level, levelmin = 1.0;
  3575. if(chanspan > 1.0)
  3576. levelmin = 1.0/chanspan; // minimum full-level possible, if rolloff is 1.0
  3577. level = (1.0 - levelmin) * (1.0 - rolloff);
  3578. level += levelmin;
  3579. if(chanspan < 1.0)
  3580. sidelevel = level * chanspan;
  3581. else
  3582. sidelevel = level;
  3583. for(n=0;n<chans;n++) {
  3584. outchan = map[n];
  3585. maxchan = (double)outchan + halfspan;
  3586. maxfullchan = (int)floor(maxchan);
  3587. minchan = (double)outchan - halfspan;
  3588. if(minchan < 0.0)
  3589. minfullchan = -(int)floor(-minchan);
  3590. else
  3591. minfullchan = (int)ceil(minchan);
  3592. if((truminfullchan = minfullchan) < 0) // Convert outer channels to the 0 to N-1 range
  3593. truminfullchan += chans;
  3594. if((trumaxfullchan = maxfullchan) >= chans)
  3595. trumaxfullchan -= chans;
  3596. if(span > 1.0 && (truminfullchan == trumaxfullchan)) // Avoid wrap-around causing the channel opposite outchan
  3597. maxfullchan--; // Getting a double loading of signal
  3598. for(m = minfullchan;m <= maxfullchan; m++) { // Put full-level signal in all chans that are completely spanned
  3599. if((truchan = m) < 0)
  3600. truchan += chans;
  3601. else if(truchan >= chans)
  3602. truchan -= chans;
  3603. obuf[bufpos + truchan] = (float)(obuf[bufpos + truchan] + (ibuf[bufpos + n] * level));
  3604. }
  3605. partial_level = maxchan - (double)maxfullchan;
  3606. if(!flteq(partial_level, 0.0)) { // Span spreads partially to other outchans
  3607. maxfullchan++;
  3608. if((trumaxfullchan = maxfullchan) >= chans)
  3609. maxfullchan -= chans;
  3610. minfullchan--;
  3611. if((truminfullchan = minfullchan) < 0)
  3612. truminfullchan += chans;
  3613. obuf[bufpos + truminfullchan] = (float)(obuf[bufpos + truminfullchan] + (ibuf[bufpos + n] * sidelevel * partial_level));
  3614. if(truminfullchan != trumaxfullchan) // Avoid wrap-around getting double whammy
  3615. obuf[bufpos + trumaxfullchan] = (float)(obuf[bufpos + trumaxfullchan] + (ibuf[bufpos + n] * sidelevel * partial_level));
  3616. }
  3617. }
  3618. }
  3619. /*************************** PANPROCESS ****************************/
  3620. #define XSAFETY 4
  3621. int panprocess(dataptr dz)
  3622. {
  3623. int exit_status;
  3624. int blok_cnt, chans = dz->infile->channels, done;
  3625. int n, j, total_sams = dz->insams[0]/chans, centrecnt=0;
  3626. double dur = dz->duration;
  3627. int *countlimits, *counters;
  3628. double time = 0.0, start_time=0.0, start_pos=0.0, end_time=0.0, end_pos=0.0, timestep=0.0, timegap, timeratio, valdiff=0.0, valstep, val;
  3629. if((dz->parray[0] = (double *)malloc(chans * sizeof(double)))==NULL) { // level of each channel at calc point
  3630. sprintf(errstr,"INSUFFICIENT MEMORY for storing levels.\n");
  3631. return(MEMORY_ERROR);
  3632. }
  3633. if((dz->parray[1] = (double *)malloc(chans * sizeof(double)))==NULL) { // lastlevel of each channel at calc point
  3634. sprintf(errstr,"INSUFFICIENT MEMORY for storing previous levels.\n");
  3635. return(MEMORY_ERROR);
  3636. }
  3637. if((dz->lparray[0] = (int *)malloc(chans * sizeof(int)))==NULL) { // counters for number of brkpnts generated for each chan
  3638. sprintf(errstr,"INSUFFICIENT MEMORY for storing previous levels.\n");
  3639. return(MEMORY_ERROR);
  3640. }
  3641. if((dz->lparray[1] = (int *)malloc(chans * sizeof(int)))==NULL) { // counters for current count of brkpnt vals
  3642. sprintf(errstr,"INSUFFICIENT MEMORY for storing previous levels.\n");
  3643. return(MEMORY_ERROR);
  3644. }
  3645. if((dz->lparray[2] = (int *)malloc(chans * sizeof(int)))==NULL) { // updown indicators to catch spread reversals
  3646. sprintf(errstr,"INSUFFICIENT MEMORY for storing previous levels.\n");
  3647. return(MEMORY_ERROR);
  3648. }
  3649. if((dz->lparray[3] = (int *)malloc(chans * sizeof(int)))==NULL) { // last-updown value
  3650. sprintf(errstr,"INSUFFICIENT MEMORY for storing previous levels.\n");
  3651. return(MEMORY_ERROR);
  3652. } // counters
  3653. countlimits = dz->lparray[0];
  3654. counters = dz->lparray[1];
  3655. for(n = 0;n<chans; n++) {
  3656. countlimits[n] = 0;
  3657. counters[n] = 0;
  3658. }
  3659. if(dz->brksize[0]) {
  3660. centrecnt = 0;
  3661. start_time = dz->brk[0][centrecnt++];
  3662. start_pos = dz->brk[0][centrecnt++];
  3663. if(centrecnt >= dz->brksize[0] * 2) {
  3664. end_pos = start_pos;
  3665. end_time = dur;
  3666. } else {
  3667. end_time = dz->brk[0][centrecnt++];
  3668. end_pos = dz->brk[0][centrecnt++];
  3669. }
  3670. timestep = end_time - start_time;
  3671. valdiff = fabs(end_pos - start_pos); // Force shortest route
  3672. if(valdiff > chans/2) { // 8 -> 2 becomes 0 ->2 7->2 becomes -1 -> 2
  3673. if(end_pos > start_pos) // But 8->5 stays as it is
  3674. end_pos -= chans;
  3675. else
  3676. start_pos -= chans;
  3677. }
  3678. valdiff = end_pos - start_pos;
  3679. dz->param[0] = start_pos;
  3680. }
  3681. spread_pan_array_cnt(0.0,0,dz);
  3682. blok_cnt = 0;
  3683. for(n=0;n<total_sams;n++) {
  3684. if((n > 0) && (blok_cnt % 256 == 0)) {
  3685. time = (double)n/(double)dz->infile->srate;
  3686. if(dz->brksize[0]) {
  3687. if(time >= end_time) {
  3688. start_time = end_time;
  3689. start_pos = end_pos;
  3690. if(centrecnt >= dz->brksize[0] * 2) {
  3691. end_pos = start_pos;
  3692. end_time = dur;
  3693. } else {
  3694. end_time = dz->brk[0][centrecnt++];
  3695. end_pos = dz->brk[0][centrecnt++];
  3696. }
  3697. timestep = end_time - start_time;
  3698. valdiff = fabs(end_pos - start_pos); // Force shortest route
  3699. if(valdiff > chans/2) { // 8 -> 2 becomes 0 ->2 7->2 becomes -1 -> 2
  3700. if(end_pos > start_pos) // But 8->5 stays as it is
  3701. end_pos -= chans;
  3702. else
  3703. start_pos -= chans;
  3704. }
  3705. valdiff = end_pos - start_pos;
  3706. }
  3707. timegap = time - start_time;
  3708. timeratio = timegap/timestep;
  3709. valstep = valdiff * timeratio;
  3710. if((val = start_pos + valstep) < 0)
  3711. val += (double)chans;
  3712. dz->param[0] = val;
  3713. }
  3714. if(dz->brksize[1]) {
  3715. if((exit_status = read_value_from_brktable(time,1,dz))<0)
  3716. return(exit_status);
  3717. }
  3718. spread_pan_array_cnt(time,0,dz);
  3719. blok_cnt = 0;
  3720. }
  3721. blok_cnt++;
  3722. }
  3723. done = 0;
  3724. while(!done) {
  3725. if(dz->brksize[0]) {
  3726. if(time >= end_time) {
  3727. start_time = end_time;
  3728. start_pos = end_pos;
  3729. if(centrecnt >= dz->brksize[0] * 2) {
  3730. end_pos = start_pos;
  3731. end_time = dur;
  3732. } else {
  3733. end_time = dz->brk[0][centrecnt++];
  3734. end_pos = dz->brk[0][centrecnt++];
  3735. }
  3736. if((timestep = end_time - start_time) > 0.0) {
  3737. valdiff = fabs(end_pos - start_pos); // Force shortest route
  3738. if(valdiff > chans/2) { // 8 -> 2 becomes 0 ->2 7->2 becomes -1 -> 2
  3739. if(end_pos > start_pos) // But 8->5 stays as it is
  3740. end_pos -= chans;
  3741. else
  3742. start_pos -= chans;
  3743. }
  3744. valdiff = end_pos - start_pos;
  3745. timegap = time - start_time;
  3746. timeratio = timegap/timestep;
  3747. valstep = valdiff * timeratio;
  3748. if((val = start_pos + valstep) < 0)
  3749. val += chans;
  3750. dz->param[0] = val; // If timestep = 0.0, at end of file,
  3751. } // dz->param[0] accepts same val as before
  3752. } // And an array count is forced
  3753. }
  3754. if(dz->brksize[1]) {
  3755. if((exit_status = read_value_from_brktable(time,1,dz))<0)
  3756. return(exit_status);
  3757. }
  3758. spread_pan_array_cnt(time,1,dz);
  3759. done = 1;
  3760. }
  3761. for(n=0,j=2;n<dz->infile->channels;n++,j++) { // breakpint data generated for each chan
  3762. if((dz->parray[j] = (double *)malloc((countlimits[n] + XSAFETY) * sizeof(double)))==NULL) {
  3763. sprintf(errstr,"INSUFFICIENT MEMORY for storing brkpnt data for channel %d.\n",n+1);
  3764. return(MEMORY_ERROR);
  3765. }
  3766. }
  3767. blok_cnt = 0;
  3768. if(dz->brksize[0]) {
  3769. centrecnt = 0;
  3770. start_time = dz->brk[0][centrecnt++];
  3771. start_pos = dz->brk[0][centrecnt++];
  3772. if(centrecnt >= dz->brksize[0] * 2) {
  3773. end_pos = start_pos;
  3774. end_time = dur;
  3775. } else {
  3776. end_time = dz->brk[0][centrecnt++];
  3777. end_pos = dz->brk[0][centrecnt++];
  3778. }
  3779. timestep = end_time - start_time;
  3780. valdiff = fabs(end_pos - start_pos); // Force shortest route
  3781. if(valdiff > chans/2) { // 8 -> 2 becomes 0 ->2 7->2 becomes -1 -> 2
  3782. if(end_pos > start_pos) // But 8->5 stays as it is
  3783. end_pos -= chans;
  3784. else
  3785. start_pos -= chans;
  3786. }
  3787. valdiff = end_pos - start_pos;
  3788. dz->param[0] = start_pos;
  3789. }
  3790. if((exit_status = spread_pan_process(0.0,0,dz)) < 0)
  3791. return(exit_status);
  3792. for(n=0;n<total_sams;n++) {
  3793. if((n > 0) && (blok_cnt % 256 == 0)) {
  3794. time = (double)n/(double)dz->infile->srate;
  3795. if(dz->brksize[0]) {
  3796. if(time >= end_time) {
  3797. start_time = end_time;
  3798. start_pos = end_pos;
  3799. if(centrecnt >= dz->brksize[0] * 2) {
  3800. end_pos = start_pos;
  3801. end_time = dur;
  3802. } else {
  3803. end_time = dz->brk[0][centrecnt++];
  3804. end_pos = dz->brk[0][centrecnt++];
  3805. }
  3806. timestep = end_time - start_time;
  3807. valdiff = fabs(end_pos - start_pos); // Force shortest route
  3808. if(valdiff > chans/2) { // 8 -> 2 becomes 0 ->2 7->2 becomes -1 -> 2
  3809. if(end_pos > start_pos) // But 8->5 stays as it is
  3810. end_pos -= chans;
  3811. else
  3812. start_pos -= chans;
  3813. }
  3814. valdiff = end_pos - start_pos;
  3815. }
  3816. timegap = time - start_time;
  3817. timeratio = timegap/timestep;
  3818. valstep = valdiff * timeratio;
  3819. if((val = start_pos + valstep) < 0)
  3820. val += chans;
  3821. dz->param[0] = val;
  3822. }
  3823. if(dz->brksize[1]) {
  3824. if((exit_status = read_value_from_brktable(time,1,dz))<0)
  3825. return(exit_status);
  3826. }
  3827. if((exit_status = spread_pan_process(time,0,dz)) < 0)
  3828. return(exit_status);
  3829. blok_cnt = 0;
  3830. }
  3831. blok_cnt++;
  3832. }
  3833. time = (double)n/(double)dz->infile->srate; // Force read at end of file
  3834. done = 0;
  3835. while(!done) {
  3836. if(dz->brksize[0]) {
  3837. if(time >= end_time) {
  3838. start_time = end_time;
  3839. start_pos = end_pos;
  3840. if(centrecnt >= dz->brksize[0] * 2) {
  3841. end_pos = start_pos;
  3842. end_time = dur;
  3843. } else {
  3844. end_time = dz->brk[0][centrecnt++];
  3845. end_pos = dz->brk[0][centrecnt++];
  3846. }
  3847. if((timestep = time - start_time) > 0) {
  3848. valdiff = fabs(end_pos - start_pos); // Force shortest route
  3849. if(valdiff > chans/2) { // 8 -> 2 becomes 0 ->2 7->2 becomes -1 -> 2
  3850. if(end_pos > start_pos) // But 8->5 stays as it is
  3851. end_pos -= chans;
  3852. else
  3853. start_pos -= chans;
  3854. }
  3855. valdiff = end_pos - start_pos;
  3856. timegap = time - start_time;
  3857. timeratio = timegap/timestep;
  3858. valstep = valdiff * timeratio;
  3859. if((val = start_pos + valstep) < 0)
  3860. val += chans;
  3861. dz->param[0] = val; // If timestep = 0.0, at end of file,
  3862. } // dz->param[0] accepts same val as before
  3863. } // And a write is forced (in case no final write made)
  3864. }
  3865. if(dz->brksize[1]) {
  3866. if((exit_status = read_value_from_brktable(time,1,dz))<0)
  3867. return(exit_status);
  3868. }
  3869. if((exit_status = spread_pan_process(time,1,dz)) < 0)
  3870. return(exit_status);
  3871. done = 1;
  3872. }
  3873. for(j=0;j<chans;j++)
  3874. countlimits[j] = counters[j];
  3875. if((exit_status = write_break_data(dz)) < 0)
  3876. return(exit_status);
  3877. return(FINISHED);
  3878. }
  3879. /*************************** SPREAD_PAN_PROCESS ****************************/
  3880. int spread_pan_process(double time,int last,dataptr dz)
  3881. {
  3882. int outchans = dz->infile->channels;
  3883. double centre = dz->param[0];
  3884. double spread = dz->param[1];
  3885. double halfspread = spread/2.0;
  3886. double *levels = dz->parray[0];
  3887. double *lastlevels = dz->parray[1];
  3888. int *countlimits = dz->lparray[0];
  3889. int *counters = dz->lparray[1];
  3890. int *up = dz->lparray[2];
  3891. int *lastup = dz->lparray[3];
  3892. double spredej_left, spredej_right, pos;
  3893. int spredej_left_leftchan, spredej_right_leftchan, spredej_right_rightchan, m, k, k1, k2, j, ochan;
  3894. double stereopos_left, stereopos_right;
  3895. double zleft, zright, floor_zleft, floor_zright;
  3896. double left_leftchan_level, right_rightchan_level, spredej_left_rightchan;
  3897. for(ochan = 0;ochan<outchans; ochan++)
  3898. levels[ochan] = 0.0;
  3899. if((centre = centre - 1.0) < 0.0)
  3900. centre += (double)outchans;
  3901. // Set all channels fully within the spread to 1.0
  3902. spredej_left = centre - halfspread;
  3903. while(spredej_left < 0)
  3904. spredej_left += (double)outchans;
  3905. spredej_right = centre + halfspread;
  3906. while(spredej_right >= outchans)
  3907. spredej_right -= (double)outchans;
  3908. spredej_left_leftchan = (int)floor(spredej_left);
  3909. if((spredej_left_rightchan = spredej_left_leftchan + 1) >= outchans)
  3910. spredej_left_rightchan = 0;
  3911. spredej_right_leftchan = (int)floor(spredej_right);
  3912. if(flteq(spread,0.0)) {
  3913. k1 = (int)floor(centre);
  3914. pos = centre - k1;
  3915. levels[k1] = (1.0 - pos);
  3916. k2 = k1;
  3917. if(++k2 >= outchans)
  3918. k2 -= outchans;
  3919. levels[k2] = pos;
  3920. for(k = 0;k<outchans; k++) {
  3921. if(k != k1 && k != k2)
  3922. levels[k] = 0.0;
  3923. }
  3924. } else if(spread >= outchans) {
  3925. for(k = 0;k<outchans; k++)
  3926. levels[k] = 1.0;
  3927. } else if(spread > 1.0) {
  3928. k = spredej_left_leftchan;
  3929. if(spredej_left_leftchan == spredej_left)
  3930. levels[k] = 1.0;
  3931. if(++k >= outchans)
  3932. k -= outchans;
  3933. while(k != spredej_right_leftchan) {
  3934. levels[k] = 1.0;
  3935. if(++k >= outchans)
  3936. k -= outchans;
  3937. }
  3938. levels[spredej_right_leftchan] = 1.0;
  3939. } else {
  3940. /* Deal with case where spread extends to both sides of a channel, even if less than 1.0 */
  3941. zleft = centre - halfspread;
  3942. zright = centre + halfspread;
  3943. if(zleft < 0.0) {
  3944. zleft += outchans;
  3945. zright += outchans;
  3946. }
  3947. if(zleft >= 0.0)
  3948. floor_zleft = floor(zleft);
  3949. else
  3950. floor_zleft = -ceil(fabs(zleft));
  3951. if(zright >= 0.0)
  3952. floor_zright = floor(zright);
  3953. else
  3954. floor_zright = -ceil(fabs(zright));
  3955. if(floor_zleft < floor_zright)
  3956. levels[spredej_right_leftchan] = 1.0;
  3957. }
  3958. /* Do fractional channels on leading edges of spread */
  3959. if(!flteq(spread,0.0)) {
  3960. stereopos_left = spredej_left - (double)spredej_left_leftchan;
  3961. left_leftchan_level = 1 - stereopos_left;
  3962. if(spredej_left_leftchan != spredej_right_leftchan)
  3963. levels[spredej_left_leftchan] = left_leftchan_level;
  3964. stereopos_right = spredej_right - (double)spredej_right_leftchan;
  3965. right_rightchan_level = stereopos_right;
  3966. if(spredej_right > spredej_right_leftchan) {
  3967. if((spredej_right_rightchan = spredej_right_leftchan + 1) >= outchans)
  3968. spredej_right_rightchan -= outchans;
  3969. if(spredej_right_rightchan != spredej_left_rightchan) {
  3970. if(spredej_right_rightchan == spredej_left_leftchan) {
  3971. levels[spredej_right_rightchan] += right_rightchan_level;
  3972. } else {
  3973. levels[spredej_right_rightchan] = right_rightchan_level;
  3974. }
  3975. }
  3976. }
  3977. }
  3978. m = 0;
  3979. for(k = 0,j = 2;k<outchans; k++,j++) {
  3980. m = counters[k];
  3981. if(time <= 0.0) {
  3982. if(m+1 >= countlimits[k] + XSAFETY) {
  3983. sprintf(errstr,"Array overrun (3) for channel %d.\n",k+1);
  3984. return(PROGRAM_ERROR);
  3985. }
  3986. dz->parray[j][m++] = time;
  3987. dz->parray[j][m++] = levels[k];
  3988. } else if(last) {
  3989. if(m+1 >= countlimits[k] + XSAFETY) {
  3990. sprintf(errstr,"Array overrun (3) for channel %d\n",k+1);
  3991. return(PROGRAM_ERROR);
  3992. }
  3993. if(time > dz->parray[j][m-2]) {
  3994. dz->parray[j][m++] = time;
  3995. dz->parray[j][m++] = levels[k];
  3996. }
  3997. } else {
  3998. if(levels[k] <= 0.0 && lastlevels[k] > 0.0) {
  3999. if(m+1 >= countlimits[k] + XSAFETY) {
  4000. sprintf(errstr,"Array overrun (1) for channel %d.\n",k+1);
  4001. return(PROGRAM_ERROR);
  4002. }
  4003. dz->parray[j][m++] = time;
  4004. dz->parray[j][m++] = levels[k];
  4005. } else if(lastlevels[k] <= 0.0 && levels[k] > 0.0) {
  4006. if(m+1 >= countlimits[k] + XSAFETY) {
  4007. sprintf(errstr,"Array overrun (1) for channel %d.\n",k+1);
  4008. return(PROGRAM_ERROR);
  4009. }
  4010. dz->parray[j][m++] = time;
  4011. dz->parray[j][m++] = lastlevels[k];
  4012. } else if (levels[k] >= 1.0 && lastlevels[k] < 1.0) {
  4013. if(m+1 >= countlimits[k] + XSAFETY) {
  4014. sprintf(errstr,"Array overrun (2) for channel %d.\n",k+1);
  4015. return(PROGRAM_ERROR);
  4016. }
  4017. dz->parray[j][m++] = time;
  4018. dz->parray[j][m++] = levels[k];
  4019. } else if (lastlevels[k] >= 1.0 && levels[k] < 1.0) {
  4020. if(m+1 >= countlimits[k] + XSAFETY) {
  4021. sprintf(errstr,"Array overrun (2) for channel %d.\n",k+1);
  4022. return(PROGRAM_ERROR);
  4023. }
  4024. dz->parray[j][m++] = time;
  4025. dz->parray[j][m++] = lastlevels[k];
  4026. } else {
  4027. if(levels[k] - lastlevels[k] > 0)
  4028. up[k] = 1;
  4029. if(levels[k] - lastlevels[k] < 0)
  4030. up[k] = -1;
  4031. else
  4032. up[k] = 0;
  4033. if(up[k] != lastup[k]) { // Level change can change direction of spread reverses
  4034. if(m+1 >= countlimits[k] + XSAFETY) {
  4035. sprintf(errstr,"Array overrun (3) for channel %d.\n",k+1);
  4036. return(PROGRAM_ERROR);
  4037. }
  4038. dz->parray[j][m++] = time;
  4039. dz->parray[j][m++] = levels[k];
  4040. }
  4041. }
  4042. }
  4043. lastlevels[k] = levels[k];
  4044. lastup[k] = up[k];
  4045. counters[k] = m;
  4046. }
  4047. return(FINISHED);
  4048. }
  4049. /*************************** SPREAD_PAN_ARRAY_CNT ****************************/
  4050. void spread_pan_array_cnt(double time,int last,dataptr dz)
  4051. {
  4052. int outchans = dz->infile->channels;
  4053. double centre = dz->param[0];
  4054. double spread = dz->param[1];
  4055. double halfspread = spread/2.0;
  4056. double *levels = dz->parray[0];
  4057. double *lastlevels = dz->parray[1];
  4058. int *countlimits = dz->lparray[0];
  4059. int *up = dz->lparray[2];
  4060. int *lastup = dz->lparray[3];
  4061. double spredej_left, spredej_right, pos;
  4062. int spredej_left_leftchan, spredej_right_leftchan, spredej_right_rightchan, k, k1, k2, ochan;
  4063. double stereopos_left, stereopos_right;
  4064. double zleft, zright, floor_zleft, floor_zright;
  4065. double left_leftchan_level, right_rightchan_level, spredej_left_rightchan;
  4066. for(ochan = 0;ochan<outchans; ochan++)
  4067. levels[ochan] = 0.0;
  4068. if((centre = centre - 1.0) < 0.0)
  4069. centre += (double)outchans;
  4070. // Set all channels fully within the spread to 1.0
  4071. spredej_left = centre - halfspread;
  4072. while(spredej_left < 0)
  4073. spredej_left += (double)outchans;
  4074. spredej_right = centre + halfspread;
  4075. while(spredej_right >= outchans)
  4076. spredej_right -= (double)outchans;
  4077. spredej_left_leftchan = (int)floor(spredej_left);
  4078. if((spredej_left_rightchan = spredej_left_leftchan + 1) >= outchans)
  4079. spredej_left_rightchan = 0;
  4080. spredej_right_leftchan = (int)floor(spredej_right);
  4081. if(flteq(spread,0.0)) {
  4082. k1 = (int)floor(centre);
  4083. pos = centre - k1;
  4084. levels[k1] = (1.0 - pos);
  4085. k2 = k1;
  4086. if(++k2 >= outchans)
  4087. k2 -= outchans;
  4088. levels[k2] = pos;
  4089. for(k = 0;k<outchans; k++) {
  4090. if(k != k1 && k != k2)
  4091. levels[k] = 0.0;
  4092. }
  4093. } else if(spread >= outchans) {
  4094. for(k = 0;k<outchans; k++)
  4095. levels[k] = 1.0;
  4096. return;
  4097. } else if(spread > 1.0) {
  4098. k = spredej_left_leftchan;
  4099. if(spredej_left_leftchan == spredej_left)
  4100. levels[k] = 1.0;
  4101. if(++k >= outchans)
  4102. k -= outchans;
  4103. while(k != spredej_right_leftchan) {
  4104. levels[k] = 1.0;
  4105. if(++k >= outchans)
  4106. k -= outchans;
  4107. }
  4108. levels[spredej_right_leftchan] = 1.0;
  4109. } else {
  4110. /* Deal with case where spread extends to both sides of a channel, even if less than 1.0 */
  4111. zleft = centre - halfspread;
  4112. zright = centre + halfspread;
  4113. if(zleft < 0.0) {
  4114. zleft += outchans;
  4115. zright += outchans;
  4116. }
  4117. if(zleft >= 0.0)
  4118. floor_zleft = floor(zleft);
  4119. else
  4120. floor_zleft = -ceil(fabs(zleft));
  4121. if(zright >= 0.0)
  4122. floor_zright = floor(zright);
  4123. else
  4124. floor_zright = -ceil(fabs(zright));
  4125. if(floor_zleft < floor_zright)
  4126. levels[spredej_right_leftchan] = 1.0;
  4127. }
  4128. /* Do fractional channels on leading edges of spread */
  4129. if(!flteq(spread,0.0)) {
  4130. stereopos_left = spredej_left - (double)spredej_left_leftchan;
  4131. left_leftchan_level = 1 - stereopos_left;
  4132. if(spredej_left_leftchan != spredej_right_leftchan)
  4133. levels[spredej_left_leftchan] = left_leftchan_level;
  4134. stereopos_right = spredej_right - (double)spredej_right_leftchan;
  4135. right_rightchan_level = stereopos_right;
  4136. if(spredej_right > spredej_right_leftchan) {
  4137. if((spredej_right_rightchan = spredej_right_leftchan + 1) >= outchans)
  4138. spredej_right_rightchan -= outchans;
  4139. if(spredej_right_rightchan != spredej_left_rightchan) {
  4140. if(spredej_right_rightchan == spredej_left_leftchan) {
  4141. levels[spredej_right_rightchan] += right_rightchan_level;
  4142. } else {
  4143. levels[spredej_right_rightchan] = right_rightchan_level;
  4144. }
  4145. }
  4146. }
  4147. }
  4148. for(k = 0;k<outchans; k++) {
  4149. if(last || (time <= 0.0))
  4150. countlimits[k] += 2;
  4151. else {
  4152. if(levels[k] <= 0.0 && lastlevels[k] > 0.0) {
  4153. countlimits[k] += 2;
  4154. } else if(lastlevels[k] <= 0.0 && levels[k] > 0.0) {
  4155. countlimits[k] += 2;
  4156. } else if (levels[k] >= 1.0 && lastlevels[k] < 1.0) {
  4157. countlimits[k] += 2;
  4158. } else if (lastlevels[k] >= 1.0 && levels[k] < 1.0) {
  4159. countlimits[k] += 2;
  4160. } else {
  4161. if(levels[k] - lastlevels[k] > 0)
  4162. up[k] = 1;
  4163. if(levels[k] - lastlevels[k] < 0)
  4164. up[k] = -1;
  4165. else
  4166. up[k] = 0;
  4167. if(up[k] != lastup[k]) { // Level can change if direction of spread reverses
  4168. countlimits[k] += 2;
  4169. }
  4170. }
  4171. }
  4172. lastlevels[k] = levels[k];
  4173. lastup[k] = up[k];
  4174. }
  4175. }
  4176. /*************************** WRITE_BREAK_DATA ****************************/
  4177. int write_break_data(dataptr dz)
  4178. {
  4179. char filename[48], temp[20];
  4180. double *data;
  4181. int j, k, outchans = dz->infile->channels;
  4182. int i, cnt;
  4183. FILE *fp;
  4184. for(k = 0,j = 2;k<outchans; k++,j++) {
  4185. data = dz->parray[j];
  4186. strcpy(filename,"cdptest");
  4187. sprintf(temp,"%d",k+1);
  4188. strcat(filename,temp);
  4189. strcat(filename,".txt");
  4190. if((fp = fopen(filename,"w"))==NULL) {
  4191. sprintf(errstr,"Cannot open output file %s\n",filename);
  4192. return(DATA_ERROR);
  4193. }
  4194. cnt = dz->lparray[0][k]; // count of entries in dz->parray[k]
  4195. for(i=0;i < cnt;i+=2)
  4196. fprintf(fp,"%lf\t%lf\n",data[i],data[i+1]);
  4197. if(fclose(fp)<0) {
  4198. sprintf(errstr,"WARNING: Failed to close output textfile %s.\n",filename);
  4199. return(DATA_ERROR);
  4200. }
  4201. }
  4202. return(FINISHED);
  4203. }
  4204. /************************************************ MCHANPAN2 ******************************************
  4205. *
  4206. * Rotate mono file, giving speed in a breakpoint file.
  4207. */
  4208. #define MCHANPAN2_OCHANS 0
  4209. #define MCHANPAN2_STARTCH 1
  4210. #define MCHANPAN2_SPEED 2
  4211. int mchanpan2(dataptr dz)
  4212. {
  4213. int exit_status;
  4214. int outchans = dz->iparam[MCHANPAN2_OCHANS];
  4215. double doutchans = (double)outchans;
  4216. double srate = (double)dz->infile->srate;
  4217. double chans_per_sec, chans_per_samp = 0.0;
  4218. double position = dz->param[MCHANPAN2_STARTCH], time = 0.0;
  4219. double leftgain, rightgain, farleftgain, farrightgain;
  4220. int leftchan, farleftchan, rightchan, farrightchan;
  4221. int pantype = 1;
  4222. int ibufpos = 0, obufpos = 0;
  4223. float *ibuf = dz->sampbuf[0];
  4224. float *obuf = dz->sampbuf[1];
  4225. int obuflen = dz->buflen * dz->iparam[MCHANPAN2_OCHANS];
  4226. int total_samps_processed = 0;
  4227. memset((char *)obuf,0,obuflen * sizeof(float));
  4228. if((exit_status = read_samps(ibuf,dz))<0) {
  4229. sprintf(errstr,"Failed to read data from sndfile.\n");
  4230. return(DATA_ERROR);
  4231. }
  4232. if (dz->brksize[MCHANPAN2_SPEED] == 0) {
  4233. chans_per_sec = dz->param[MCHANPAN2_SPEED] * doutchans;
  4234. chans_per_samp = chans_per_sec/srate;
  4235. if(dz->vflag[0])
  4236. chans_per_samp = -chans_per_samp;
  4237. }
  4238. while(total_samps_processed < dz->insams[0]) {
  4239. if(total_samps_processed % 256 == 0) {
  4240. if(dz->brksize[MCHANPAN2_SPEED]) {
  4241. time = (double)total_samps_processed/srate;
  4242. if((exit_status = read_value_from_brktable(time,MCHANPAN2_SPEED,dz)) < 0)
  4243. return exit_status;
  4244. chans_per_sec = dz->param[MCHANPAN2_SPEED] * doutchans;
  4245. chans_per_samp = chans_per_sec/srate;
  4246. if(dz->vflag[0])
  4247. chans_per_samp = -chans_per_samp;
  4248. }
  4249. }
  4250. position += chans_per_samp;
  4251. if(position > doutchans) /* position = lspkr no (or some fraction inbetween) (range 1 - outchans) */
  4252. position -= doutchans; /* Convention is that vals 1 to 8 refers to positions at or between lspkrs 1-8 */
  4253. else if(position < 0.0) /* while values below 1 refer to positions between lspkr 8 and lspkr 1, in the 'circle' */
  4254. position += doutchans; /* We adjust here, when position-incrementation takes position beyond these limits */
  4255. mchan_pancalc(position,&leftgain,&rightgain,&farleftgain,&farrightgain,&leftchan,pantype,3,dz);
  4256. leftchan--; /* output bufs numbered from 0 */
  4257. farleftchan = (leftchan + outchans - 1) % outchans; /* output chans are adjacent, L and R refer to lspkrs to left and right of current position */
  4258. rightchan = (leftchan + 1) % outchans; /* farleft and farright are speakers next to left and right spkrs, for any unfocused signal */
  4259. farrightchan = (rightchan + 1) % outchans;
  4260. obuf[obufpos + farleftchan] = (float)(obuf[obufpos + farleftchan] + (ibuf[ibufpos] * farleftgain));
  4261. obuf[obufpos + leftchan] = (float)(obuf[obufpos + leftchan] + (ibuf[ibufpos] * leftgain));
  4262. obuf[obufpos + rightchan] = (float)(obuf[obufpos + rightchan] + (ibuf[ibufpos] * rightgain));
  4263. obuf[obufpos + farrightchan] = (float)(obuf[obufpos + farrightchan] + (ibuf[ibufpos] * farrightgain));
  4264. ibufpos++;
  4265. obufpos += outchans;
  4266. if(ibufpos >= dz->buflen) {
  4267. if((exit_status = read_samps(ibuf,dz))<0) {
  4268. sprintf(errstr,"Failed to read data from sndfile.\n");
  4269. return(DATA_ERROR);
  4270. }
  4271. if(dz->ssampsread == 0)
  4272. break;
  4273. ibufpos = 0;
  4274. }
  4275. if(obufpos >= obuflen) {
  4276. if((exit_status = write_samps(obuf,obuflen,dz))<0)
  4277. return(exit_status);
  4278. memset((char *)obuf,0,obuflen * sizeof(float));
  4279. obufpos = 0;
  4280. }
  4281. total_samps_processed++;
  4282. }
  4283. if(obufpos > 0) {
  4284. if((exit_status = write_samps(obuf,obufpos,dz))<0)
  4285. return(exit_status);
  4286. }
  4287. return FINISHED;
  4288. }
  4289. /*************************** PERMUTE_CHANS ***************************/
  4290. void permute_chans(int outchans,dataptr dz)
  4291. {
  4292. int n, t;
  4293. for(n=0;n<outchans;n++) {
  4294. t = (int)(drand48() * (double)(n+1)); /* TRUNCATE */
  4295. if(t==n)
  4296. prefixch(n,outchans,dz);
  4297. else
  4298. insertch(n,t,outchans,dz);
  4299. }
  4300. }
  4301. /****************************** INSERTCH ****************************/
  4302. void insertch(int n,int t,int outchans,dataptr dz)
  4303. {
  4304. shuflupch(t+1,outchans,dz);
  4305. dz->iparray[0][t+1] = n;
  4306. }
  4307. /****************************** PREFIX ****************************/
  4308. void prefixch(int n,int outchans,dataptr dz)
  4309. {
  4310. shuflupch(0,outchans,dz);
  4311. dz->iparray[0][0] = n;
  4312. }
  4313. /****************************** SHUFLUPCH ****************************/
  4314. void shuflupch(int k,int outchans,dataptr dz)
  4315. {
  4316. int n;
  4317. for(n = outchans - 1; n > k; n--)
  4318. dz->iparray[0][n] = dz->iparray[0][n-1];
  4319. }
  4320. /*************************** ADJACENCE **************************/
  4321. int adjacence(int endchan,dataptr dz)
  4322. {
  4323. int *perm = dz->iparray[0];
  4324. int i, j, ochans = dz->iparam[0];
  4325. int lastchan = ochans - 1;
  4326. if(dz->vflag[0] == 0)
  4327. return 0;
  4328. if(endchan >= 0) {
  4329. if ((perm[0] == 0) && (endchan == lastchan))
  4330. return 1;
  4331. else if((endchan == 0) && (perm[0] == lastchan))
  4332. return 1;
  4333. else if(perm[0] - endchan == 1)
  4334. return 1;
  4335. else if(endchan - perm[0] == 1)
  4336. return 1;
  4337. }
  4338. for(i=0;i < ochans;i++) {
  4339. j = (i + 1) % ochans;
  4340. if ((perm[i] == 0) && (perm[j] == lastchan))
  4341. return 1;
  4342. else if((perm[j] == 0) && (perm[i] == lastchan))
  4343. return 1;
  4344. else if(perm[j] - perm[i] == 1)
  4345. return 1;
  4346. else if(perm[i] - perm[j] == 1)
  4347. return 1;
  4348. }
  4349. return 0;
  4350. }
  4351. // cmdline: mchanpan mchanpan 8 infile centre spread keyparam
  4352. //
  4353. // MODE 7(8) output is
  4354. // brkpnt files cdptest1 to N .txt
  4355. // Where a key param of process can reduce process effect to zero, breakpoint replaces key param (Key param must NOT timevary)
  4356. // Where this is not true, brkpnt use to control mix balance (keyparam = 0)