specnu-800.c 211 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271
  1. /*
  2. * Copyright (c) 1983-2020 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. /* RWD 15/12/20 remove usage handling for "sync" */
  22. #include <stdio.h>
  23. #include <stdlib.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 <speccon.h>
  38. #include <repitch.h>
  39. #include <formants.h>
  40. #include <flags.h>
  41. #include <ctype.h>
  42. #include <sfsys.h>
  43. #include <string.h>
  44. #include <srates.h>
  45. #if defined unix || defined __GNUC__
  46. #define round(x) lround((x))
  47. #endif
  48. #ifndef HUGE
  49. #define HUGE 3.40282347e+38F
  50. #endif
  51. #define total_windows_read rampbrksize
  52. #define last_windows_read temp_sampsize
  53. #define total_windows_written buflen2
  54. #define maxfraccnt linecnt
  55. #define harmcnt linecnt
  56. #define copycnt temp_sampsize
  57. #define SPEX_TIM 0
  58. #define SPEX_DUR 1
  59. #define SPEX_STR 2
  60. #define SPEX_WIN 3
  61. #define SPEX_STT 0
  62. #define SPEX_END 1
  63. #define INV_BOT 0
  64. #define INV_TOP 1
  65. #define INV_PKTOP 2
  66. #define INV_GAIN 3
  67. #define ENDPAD_WINDOWS 16
  68. char errstr[2400];
  69. int anal_infiles = 1;
  70. int sloom = 0;
  71. int sloombatch = 0;
  72. const char* cdp_version = "8.0.0";
  73. /* CDP LIBRARY FUNCTIONS TRANSFERRED HERE */
  74. static int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist);
  75. static int set_vflgs(aplptr ap,char *optflags,int optcnt,char *optlist,
  76. char *varflags,int vflagcnt, int vparamcnt,char *varlist);
  77. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  78. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  79. static int mark_parameter_types(dataptr dz,aplptr ap);
  80. static int establish_application(dataptr dz);
  81. static int application_init(dataptr dz);
  82. static int initialise_vflags(dataptr dz);
  83. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  84. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  85. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  86. static int assign_file_data_storage(int infilecnt,dataptr dz);
  87. /* CDP LIB FUNCTION MODIFIED TO AVOID CALLING setup_particular_application() */
  88. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  89. /* SIMPLIFICATION OF LIB FUNC TO APPLY TO JUST THIS FUNCTION */
  90. static int parse_infile_and_check_type(char **cmdline,dataptr dz);
  91. static int handle_the_extra_infile(char ***cmdline,int *cmdlinecnt,dataptr dz);
  92. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,int is_launched,dataptr dz);
  93. static int setup_the_application(dataptr dz);
  94. static int setup_the_param_ranges_and_defaults(dataptr dz);
  95. static int check_the_param_validity_and_consistency(dataptr dz);
  96. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  97. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  98. static int get_the_mode_no(char *str, dataptr dz);
  99. /* BYPASS LIBRARY GLOBAL FUNCTION TO GO DIRECTLY TO SPECIFIC APPLIC FUNCTIONS */
  100. static int spec_remove(dataptr dz);
  101. static int do_speclean(int subtract,dataptr dz);
  102. static int allocate_speclean_buffer(dataptr dz);
  103. static int handle_pitchdata(int *cmdlinecnt,char ***cmdline,dataptr dz);
  104. static void insert_newnumber_at_filename_end(char *filename,int num,int overwrite_last_char);
  105. static int create_next_outfile(dataptr dz);
  106. static int do_specslice(dataptr dz);
  107. static int setup_specslice_parameter_storage(dataptr dz);
  108. static int specpivot(dataptr dz);
  109. static int specrand(dataptr dz);
  110. static int specsqz(dataptr dz);
  111. static void rndintperm(int *perm,int cnt);
  112. static int allocate_specsqz_buffer(dataptr dz);
  113. static int specex(dataptr dz);
  114. static int create_specex_buffers(dataptr dz);
  115. // static int handle_syncdata(int *cmdlinecnt,char ***cmdline,dataptr dz);
  116. // static int create_sync_buffers(dataptr dz);
  117. static int advance_along_input_windows(int wdw_to_advance,dataptr dz);
  118. static int generate_zero_window(int *owcnt,int atend,dataptr dz);
  119. static int copy_final_window(int *owcnt,dataptr dz);
  120. static int do_timestretching(int *thatwindow,int *owcnt,double abswinptr,dataptr dz);
  121. // static int specsync(dataptr dz);
  122. // static void force_wav_extension(char *filename);
  123. static int transpart(dataptr dz);
  124. static int transpose_within_formant_envelope(int vc,dataptr dz);
  125. static int re_position_partials_in_appropriate_channels(dataptr dz);
  126. #ifdef NOTDEF
  127. //RWD: NOT USED
  128. static int spec_trnsp(dataptr dz);
  129. static int spec_trnsf(dataptr dz);
  130. #endif
  131. static int setup_formants(dataptr dz);
  132. static int set_spec_env_frqs(int arraycnt,dataptr dz);
  133. static int setup_octave_band_steps(double **interval,dataptr dz);
  134. static int setup_lo_octave_bands(int arraycnt,dataptr dz);
  135. static int extract_spec_env(int storeno,dataptr dz);
  136. static int move_data_into_appropriate_chan(int vc,int truevc,float thisamp,float thisfrq,dataptr dz) ;
  137. static int specnu_normalise(double pre_totalamp,double post_totalamp,int paramno,dataptr dz);
  138. static int spec_keep_formants(int ccbot,int cctop,dataptr dz);
  139. static int shift_within_formant_envelope(int vc,dataptr dz);
  140. static int spec_move_formants(int ccbot,int cctop,dataptr dz);
  141. static int nuinvert(dataptr dz);
  142. static int invert_spectrum(int ccbot,int cctop,int ccpk,int wins_read,dataptr dz);
  143. static int find_maxamp_channel(int cclo,int cchi,float *maxamp,dataptr dz);
  144. static int find_minamp_channel(int cclo,int cchi,float *minamp,dataptr dz);
  145. static int create_contours(float maxamplo,float maxamphi,int botmaxloc,int topmaxloc,int cctop,dataptr dz);
  146. static int do_spectral_invert(int ccbot,int cctop,float amprange,float minamp,dataptr dz);
  147. static int allocate_quad_buffer(dataptr dz);
  148. static int convolve(dataptr dz);
  149. static int self_convolve(float *buf,int *wins_read,double *ratio,double *ratiosum,double *maxin,double *maxout,int passno,dataptr dz);
  150. static int do_convolve(float *buf,float *buflast,float *buf2,float *buf2last,int *wins_read,double *ratio,double *ratiosum,
  151. double *maxin,double *maxout,int passno,dataptr dz);
  152. static double chanadjust(double frq,double fbot,double ftop,dataptr dz);
  153. static int do_specsnd(int *obufcnt,int positive,double transbot,double transrange,dataptr dz);
  154. static int specsnd(dataptr dz);
  155. static int create_specfrac_buffers(dataptr dz);
  156. static int check_fractal_param_validity_and_consistency(dataptr dz);
  157. static int specfrac(dataptr dz);
  158. static int fractal_copy_and_shrink(dataptr dz);
  159. static int fractal_copy_reverse_shorten(dataptr dz);
  160. static int frac_copy(int *bufpos,int startwin,int endwin,dataptr dz);
  161. static int frac_reverse_copy(int *bufpos,int startwin,int endwin,dataptr dz);
  162. static int frac_interp_shrink(dataptr dz);
  163. static int create_new_outfile(int n,char *outfilename,dataptr dz);
  164. static int frac_add_shrink(dataptr dz);
  165. static int fractal_reverse_copy_and_shrink(dataptr dz);
  166. static int frac_reverse_second_half(int *buf2pos,int startwin,int endwin,dataptr dz);
  167. static int frac_interleave(int gpcnt,dataptr dz);
  168. static int frac_interleave_reverse(int gpcnt,dataptr dz);
  169. static int frac_interleave_cycle(int gpcnt,dataptr dz);
  170. static int frac_swap(int *buf2pos,int startwin,int endwin,dataptr dz);
  171. static int fractal_by_halves(dataptr dz);
  172. static int fractal_by_interleaving(dataptr dz);
  173. /**************************************** MAIN *********************************************/
  174. int main(int argc,char *argv[])
  175. {
  176. int exit_status;
  177. dataptr dz = NULL;
  178. char **cmdline;
  179. int cmdlinecnt;
  180. aplptr ap;
  181. int is_launched = FALSE;
  182. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  183. fprintf(stdout,"%s\n",cdp_version);
  184. fflush(stdout);
  185. return 0;
  186. }
  187. /* CHECK FOR SOUNDLOOM */
  188. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  189. sloom = 0;
  190. sloombatch = 1;
  191. }
  192. if(sflinit("cdp")){
  193. sfperror("cdp: initialisation\n");
  194. return(FAILED);
  195. }
  196. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  197. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  198. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  199. return(FAILED);
  200. }
  201. if(!sloom) {
  202. if(argc == 1) {
  203. usage1();
  204. return(FAILED);
  205. } else if(argc == 2) {
  206. usage2(argv[1]);
  207. return(FAILED);
  208. }
  209. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  210. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  211. return(FAILED);
  212. }
  213. cmdline = argv;
  214. cmdlinecnt = argc;
  215. if((get_the_process_no(argv[0],dz))<0)
  216. return(FAILED);
  217. cmdline++;
  218. cmdlinecnt--;
  219. switch(dz->process) {
  220. case(SPEC_REMOVE): dz->maxmode = 2; break;
  221. case(SPECLEAN): dz->maxmode = 0; break;
  222. case(SPECTRACT): dz->maxmode = 0; break;
  223. case(SPECSLICE): dz->maxmode = 5; break;
  224. case(SPECRAND): dz->maxmode = 0; break;
  225. case(SPECSQZ): dz->maxmode = 0; break;
  226. // case(SPECSYNC): dz->maxmode = 0; break;
  227. case(SPECEX): dz->maxmode = 0; break;
  228. case(TRANSPART): dz->maxmode = 8; break;
  229. case(SPECINVNU): dz->maxmode = 0; break;
  230. case(SPECCONV): dz->maxmode = 2; break;
  231. case(SPECSND): dz->maxmode = 0; break;
  232. case(SPECFRAC): dz->maxmode = 9; break;
  233. }
  234. if(dz->maxmode > 0) {
  235. if(cmdlinecnt <= 0) {
  236. sprintf(errstr,"Too few commandline parameters.\n");
  237. return(FAILED);
  238. }
  239. if((get_the_mode_no(cmdline[0],dz))<0) {
  240. if(!sloom)
  241. fprintf(stderr,"%s",errstr);
  242. return(FAILED);
  243. }
  244. cmdline++;
  245. cmdlinecnt--;
  246. }
  247. if((exit_status = setup_the_application(dz))<0) {
  248. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  249. return(FAILED);
  250. }
  251. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  252. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  253. return(FAILED);
  254. }
  255. } else {
  256. //parse_TK_data() =
  257. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  258. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  259. return(exit_status);
  260. }
  261. }
  262. ap = dz->application;
  263. // parse_infile_and_hone_type() =
  264. if((exit_status = parse_infile_and_check_type(cmdline,dz))<0) {
  265. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  266. return(FAILED);
  267. }
  268. // setup_param_ranges_and_defaults() =
  269. if((exit_status = setup_the_param_ranges_and_defaults(dz))<0) {
  270. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  271. return(FAILED);
  272. }
  273. // open_first_infile CDP LIB
  274. if((exit_status = open_first_infile(cmdline[0],dz))<0) {
  275. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  276. return(FAILED);
  277. }
  278. cmdlinecnt--;
  279. cmdline++;
  280. // handle_extra_infiles() =
  281. if(dz->process == SPECLEAN || dz->process == SPECTRACT || (dz->process == SPECCONV && dz->mode == 1)) {
  282. if((exit_status = handle_the_extra_infile(&cmdline,&cmdlinecnt,dz))<0) {
  283. if(sloom) {
  284. if(dz->process == SPECCONV && dz->mode == 1) {
  285. fprintf(stdout,"ERROR: This mode of the program needs TWO input file.\n");
  286. fflush(stdout);
  287. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  288. return(FAILED);
  289. }
  290. } else {
  291. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  292. return(FAILED);
  293. }
  294. }
  295. }
  296. // handle_outfile() =
  297. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,is_launched,dz))<0) {
  298. if(sloom && dz->process == SPECCONV && dz->mode == 0) {
  299. fprintf(stdout,"ERROR: This mode of the program only takes ONE input file\n");
  300. fflush(stdout);
  301. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  302. return(FAILED);
  303. } else {
  304. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  305. return(FAILED);
  306. }
  307. }
  308. // handle_formants() redundant
  309. // handle_formant_quiksearch() redundant
  310. // handle_special_data() redundant except
  311. if(dz->process == SPECSLICE && dz->mode == 3) {
  312. if((exit_status = handle_pitchdata(&cmdlinecnt,&cmdline,dz))<0) {
  313. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  314. return(FAILED);
  315. }
  316. }
  317. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  318. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  319. return(FAILED);
  320. }
  321. //check_param_validity_and_consistency .....
  322. if((exit_status = check_the_param_validity_and_consistency(dz))<0) {
  323. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  324. return(FAILED);
  325. }
  326. is_launched = TRUE;
  327. //allocate_large_buffers() ... replaced by CDP LIB
  328. switch(dz->process) {
  329. case(SPEC_REMOVE): dz->extra_bufcnt = 0; dz->bptrcnt = 1; break;
  330. case(SPECTRACT):
  331. case(SPECLEAN): dz->extra_bufcnt = 0; dz->bptrcnt = dz->iparam[0]; break;
  332. case(SPECSLICE): dz->extra_bufcnt = 0; dz->bptrcnt = 0; break;
  333. case(SPECRAND): dz->extra_bufcnt = 0; dz->bptrcnt = 0; break;
  334. case(SPECSQZ): dz->extra_bufcnt = 0; dz->bptrcnt = 4; break;
  335. // case(SPECSYNC): dz->extra_bufcnt = 0; dz->bptrcnt = 6; break;
  336. case(SPECEX): dz->extra_bufcnt = 0; dz->bptrcnt = 2; break;
  337. case(TRANSPART): dz->extra_bufcnt = 0; dz->bptrcnt = 2; break;
  338. case(SPECINVNU): dz->extra_bufcnt = 0; dz->bptrcnt = 5; break;
  339. case(SPECCONV): dz->extra_bufcnt = 0; dz->bptrcnt = 6; break;
  340. case(SPECSND): dz->extra_bufcnt = 0; dz->bptrcnt = 5; break;
  341. case(SPECFRAC): dz->extra_bufcnt = 0; dz->bptrcnt = 3; break;
  342. }
  343. if(dz->process == SPECEX) {
  344. if((exit_status = create_specex_buffers(dz))<0) {
  345. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  346. return(FAILED);
  347. }
  348. } else {
  349. if((exit_status = establish_spec_bufptrs_and_extra_buffers(dz))<0) {
  350. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  351. return(FAILED);
  352. }
  353. switch(dz->process) {
  354. case(SPEC_REMOVE): exit_status = allocate_single_buffer(dz); break;
  355. case(SPECRAND):
  356. case(SPECSLICE):
  357. case(SPECTRACT):
  358. case(SPECLEAN): exit_status = allocate_speclean_buffer(dz); break;
  359. case(SPECSQZ): exit_status = allocate_specsqz_buffer(dz); break;
  360. case(TRANSPART): exit_status = allocate_single_buffer(dz); break;
  361. case(SPECINVNU): exit_status = allocate_double_buffer(dz); break;
  362. case(SPECCONV):
  363. switch(dz->mode) {
  364. case(0): exit_status = allocate_double_buffer(dz); break;
  365. case(1): exit_status = allocate_quad_buffer(dz); break;
  366. }
  367. break;
  368. case(SPECSND): exit_status = allocate_double_buffer(dz); break;
  369. case(SPECFRAC): exit_status = create_specfrac_buffers(dz); break;
  370. }
  371. if(exit_status < 0) {
  372. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  373. return(FAILED);
  374. }
  375. }
  376. //param_preprocess() redundant
  377. //spec_process_file =
  378. switch(dz->process) {
  379. case(SPEC_REMOVE): exit_status = outer_loop(dz); break;
  380. case(SPECLEAN): exit_status = do_speclean(0,dz); break;
  381. case(SPECTRACT): exit_status = do_speclean(1,dz); break;
  382. case(SPECSLICE): exit_status = do_specslice(dz); break;
  383. case(SPECRAND): exit_status = specrand(dz); break;
  384. case(SPECSQZ): exit_status = specsqz(dz); break;
  385. // case(SPECSYNC): exit_status = specsync(dz); break;
  386. case(SPECEX): exit_status = specex(dz); break;
  387. case(TRANSPART): exit_status = transpart(dz); break;
  388. case(SPECINVNU): exit_status = nuinvert(dz); break;
  389. case(SPECCONV): exit_status = convolve(dz); break;
  390. case(SPECSND): exit_status = specsnd(dz); break;
  391. case(SPECFRAC): exit_status = specfrac(dz); break;
  392. }
  393. if(exit_status < 0) {
  394. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  395. return(FAILED);
  396. }
  397. if((exit_status = complete_output(dz))<0) { // CDP LIB
  398. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  399. return(FAILED);
  400. }
  401. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  402. free(dz);
  403. return(SUCCEEDED);
  404. }
  405. /**********************************************
  406. REPLACED CDP LIB FUNCTIONS
  407. **********************************************/
  408. /************************ HANDLE_THE_EXTRA_INFILE *********************/
  409. int handle_the_extra_infile(char ***cmdline,int *cmdlinecnt,dataptr dz)
  410. {
  411. /* OPEN ONE EXTRA ANALFILE, CHECK COMPATIBILITY */
  412. int exit_status;
  413. char *filename;
  414. fileptr fp2;
  415. int fileno = 1;
  416. double maxamp, maxloc;
  417. int maxrep;
  418. int getmax = 0, getmaxinfo = 0;
  419. infileptr ifp;
  420. fileptr fp1 = dz->infile;
  421. filename = (*cmdline)[0];
  422. if((dz->ifd[fileno] = sndopenEx(filename,0,CDP_OPEN_RDONLY)) < 0) {
  423. sprintf(errstr,"cannot open input file %s to read data.\n",filename);
  424. return(DATA_ERROR);
  425. }
  426. if((ifp = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  427. sprintf(errstr,"INSUFFICIENT MEMORY to store data on later infile. (1)\n");
  428. return(MEMORY_ERROR);
  429. }
  430. if((fp2 = (fileptr)malloc(sizeof(struct fileprops)))==NULL) {
  431. sprintf(errstr,"INSUFFICIENT MEMORY to store data on later infile. (2)\n");
  432. return(MEMORY_ERROR);
  433. }
  434. if((exit_status = readhead(ifp,dz->ifd[1],filename,&maxamp,&maxloc,&maxrep,getmax,getmaxinfo))<0)
  435. return(exit_status);
  436. copy_to_fileptr(ifp,fp2);
  437. if(fp2->filetype != ANALFILE) {
  438. sprintf(errstr,"%s is not an analysis file.\n",filename);
  439. return(DATA_ERROR);
  440. }
  441. if(fp2->origstype != fp1->origstype) {
  442. sprintf(errstr,"Incompatible original-sample-type in input file %s.\n",filename);
  443. return(DATA_ERROR);
  444. }
  445. if(fp2->origrate != fp1->origrate) {
  446. sprintf(errstr,"Incompatible original-sample-rate in input file %s.\n",filename);
  447. return(DATA_ERROR);
  448. }
  449. if(fp2->arate != fp1->arate) {
  450. sprintf(errstr,"Incompatible analysis-sample-rate in input file %s.\n",filename);
  451. return(DATA_ERROR);
  452. }
  453. if(fp2->Mlen != fp1->Mlen) {
  454. sprintf(errstr,"Incompatible analysis-window-length in input file %s.\n",filename);
  455. return(DATA_ERROR);
  456. }
  457. if(fp2->Dfac != fp1->Dfac) {
  458. sprintf(errstr,"Incompatible decimation factor in input file %s.\n",filename);
  459. return(DATA_ERROR);
  460. }
  461. if(fp2->channels != fp1->channels) {
  462. sprintf(errstr,"Incompatible channel-count in input file %s.\n",filename);
  463. return(DATA_ERROR);
  464. }
  465. if((dz->insams[fileno] = sndsizeEx(dz->ifd[fileno]))<0) { /* FIND SIZE OF FILE */
  466. sprintf(errstr, "Can't read size of input file %s.\n"
  467. "open_checktype_getsize_and_compareheader()\n",filename);
  468. return(PROGRAM_ERROR);
  469. }
  470. if(dz->insams[fileno]==0) {
  471. sprintf(errstr, "File %s contains no data.\n",filename);
  472. return(DATA_ERROR);
  473. }
  474. (*cmdline)++;
  475. (*cmdlinecnt)--;
  476. return(FINISHED);
  477. }
  478. /****************************** SET_PARAM_DATA *********************************/
  479. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  480. {
  481. ap->special_data = (char)special_data;
  482. ap->param_cnt = (char)paramcnt;
  483. ap->max_param_cnt = (char)maxparamcnt;
  484. if(ap->max_param_cnt>0) {
  485. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  486. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  487. return(MEMORY_ERROR);
  488. }
  489. strcpy(ap->param_list,paramlist);
  490. }
  491. return(FINISHED);
  492. }
  493. /****************************** SET_VFLGS *********************************/
  494. int set_vflgs
  495. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  496. {
  497. ap->option_cnt = (char) optcnt; /*RWD added cast */
  498. if(optcnt) {
  499. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  500. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  501. return(MEMORY_ERROR);
  502. }
  503. strcpy(ap->option_list,optlist);
  504. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  505. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  506. return(MEMORY_ERROR);
  507. }
  508. strcpy(ap->option_flags,optflags);
  509. }
  510. ap->vflag_cnt = (char) vflagcnt;
  511. ap->variant_param_cnt = (char) vparamcnt;
  512. if(vflagcnt) {
  513. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  514. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  515. return(MEMORY_ERROR);
  516. }
  517. strcpy(ap->variant_list,varlist);
  518. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  519. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  520. return(MEMORY_ERROR);
  521. }
  522. strcpy(ap->variant_flags,varflags);
  523. }
  524. return(FINISHED);
  525. }
  526. /***************************** APPLICATION_INIT **************************/
  527. int application_init(dataptr dz)
  528. {
  529. int exit_status;
  530. int storage_cnt;
  531. int tipc, brkcnt;
  532. aplptr ap = dz->application;
  533. if(ap->vflag_cnt>0)
  534. initialise_vflags(dz);
  535. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  536. ap->total_input_param_cnt = (char)tipc;
  537. if(tipc>0) {
  538. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  539. return(exit_status);
  540. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  541. return(exit_status);
  542. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  543. return(exit_status);
  544. }
  545. brkcnt = tipc;
  546. if(brkcnt>0) {
  547. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  548. return(exit_status);
  549. }
  550. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  551. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  552. return(exit_status);
  553. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  554. return(exit_status);
  555. }
  556. if((exit_status = mark_parameter_types(dz,ap))<0)
  557. return(exit_status);
  558. // establish_infile_constants() replaced by
  559. dz->infilecnt = ONE_NONSND_FILE;
  560. //establish_bufptrs_and_extra_buffers():
  561. if(dz->process == SPECSLICE && dz->mode == 3) {
  562. if((exit_status = setup_specslice_parameter_storage(dz))<0)
  563. return(exit_status);
  564. } else if(dz->process == SPECRAND) {
  565. dz->iarray_cnt=2;
  566. if((dz->iparray = (int **)malloc(dz->iarray_cnt * sizeof(int *)))==NULL) {
  567. sprintf(errstr,"INSUFFICIENT MEMORY for internal integer arrays.\n");
  568. return(MEMORY_ERROR);
  569. }
  570. } else if(dz->process == SPECEX) {
  571. dz->iarray_cnt=1;
  572. if((dz->iparray = (int **)malloc(dz->iarray_cnt * sizeof(int *)))==NULL) {
  573. sprintf(errstr,"INSUFFICIENT MEMORY for internal integer arrays.\n");
  574. return(MEMORY_ERROR);
  575. }
  576. } else if(dz->process == TRANSPART || dz->process == SPECINVNU || dz->process == SPECCONV || dz->process == SPECSND || dz->process == SPECFRAC) {
  577. ;
  578. } else {
  579. dz->array_cnt=2;
  580. if((dz->parray = (double **)malloc(dz->array_cnt * sizeof(double *)))==NULL) {
  581. sprintf(errstr,"INSUFFICIENT MEMORY for internal double arrays.\n");
  582. return(MEMORY_ERROR);
  583. }
  584. dz->parray[0] = NULL;
  585. dz->parray[1] = NULL;
  586. }
  587. return(FINISHED);
  588. }
  589. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  590. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  591. {
  592. int n;
  593. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  594. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  595. return(MEMORY_ERROR);
  596. }
  597. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  598. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  599. return(MEMORY_ERROR);
  600. }
  601. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  602. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  603. return(MEMORY_ERROR);
  604. }
  605. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  606. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  607. return(MEMORY_ERROR);
  608. }
  609. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  610. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  611. return(MEMORY_ERROR);
  612. }
  613. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  614. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  615. return(MEMORY_ERROR);
  616. }
  617. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  618. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  619. return(MEMORY_ERROR);
  620. }
  621. for(n=0;n<brkcnt;n++) {
  622. dz->brk[n] = NULL;
  623. dz->brkptr[n] = NULL;
  624. dz->brkinit[n] = 0;
  625. dz->brksize[n] = 0;
  626. }
  627. return(FINISHED);
  628. }
  629. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  630. /* RWD mallo changed to calloc; helps debug verison run as release! */
  631. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  632. {
  633. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  634. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  635. return(MEMORY_ERROR);
  636. }
  637. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  638. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  639. return(MEMORY_ERROR);
  640. }
  641. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  642. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  643. return(MEMORY_ERROR);
  644. }
  645. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  646. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  647. return(MEMORY_ERROR);
  648. }
  649. return(FINISHED);
  650. }
  651. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  652. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  653. {
  654. int n;
  655. for(n=0;n<storage_cnt;n++) {
  656. dz->is_int[n] = (char)0;
  657. dz->no_brk[n] = (char)0;
  658. }
  659. return(FINISHED);
  660. }
  661. /***************************** MARK_PARAMETER_TYPES **************************/
  662. int mark_parameter_types(dataptr dz,aplptr ap)
  663. {
  664. int n, m; /* PARAMS */
  665. for(n=0;n<ap->max_param_cnt;n++) {
  666. switch(ap->param_list[n]) {
  667. case('0'): break; /* dz->is_active[n] = 0 is default */
  668. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  669. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  670. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  671. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  672. default:
  673. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  674. return(PROGRAM_ERROR);
  675. }
  676. } /* OPTIONS */
  677. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  678. switch(ap->option_list[n]) {
  679. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  680. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  681. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  682. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  683. default:
  684. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  685. return(PROGRAM_ERROR);
  686. }
  687. } /* VARIANTS */
  688. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  689. switch(ap->variant_list[n]) {
  690. case('0'): break;
  691. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  692. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  693. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  694. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  695. default:
  696. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  697. return(PROGRAM_ERROR);
  698. }
  699. } /* INTERNAL */
  700. for(n=0,
  701. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  702. switch(ap->internal_param_list[n]) {
  703. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  704. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  705. case('d'): dz->no_brk[m] = (char)1; break;
  706. default:
  707. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  708. return(PROGRAM_ERROR);
  709. }
  710. }
  711. return(FINISHED);
  712. }
  713. /***************************** HANDLE_THE_OUTFILE **************************/
  714. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,int is_launched,dataptr dz)
  715. {
  716. int exit_status, len;
  717. int origsrate, origchans;
  718. char *filename = NULL;
  719. if(dz->process == SPECSLICE && dz->mode < 4) {
  720. if(dz->wordstor!=NULL)
  721. free_wordstors(dz);
  722. dz->all_words = 0;
  723. if((exit_status = store_filename((*cmdline)[0],dz))<0)
  724. return(exit_status);
  725. len = strlen((*cmdline)[0]);
  726. if((filename = (char *)malloc(len + 8))==NULL) {
  727. sprintf(errstr,"handle_the_outfile()\n");
  728. return(MEMORY_ERROR);
  729. }
  730. strcpy(filename,dz->wordstor[0]);
  731. dz->itemcnt = 0;
  732. } else {
  733. len = strlen((*cmdline)[0]);
  734. if((filename = (char *)malloc(len + 8))==NULL) {
  735. sprintf(errstr,"handle_the_outfile()\n");
  736. return(MEMORY_ERROR);
  737. }
  738. strcpy(filename,(*cmdline)[0]);
  739. }
  740. // if(dz->process == SPECSYNC) // Force ".wav" extension
  741. // force_wav_extension(filename);
  742. strcpy(dz->outfilename,filename);
  743. if(dz->process == SPECSND) {
  744. origchans = dz->infile->channels;
  745. origsrate = dz->infile->srate;
  746. dz->infile->channels = 1;
  747. dz->infile->srate = dz->infile->origrate;
  748. if((exit_status = create_sized_outfile(filename,dz))<0)
  749. return(exit_status);
  750. dz->infile->channels = origchans;
  751. dz->infile->channels = origsrate;
  752. } else if(dz->process == SPECRAND || dz->process == SPECSQZ || dz->process == SPECEX || dz->process == TRANSPART) {
  753. if((exit_status = create_sized_outfile(filename,dz))<0)
  754. return(exit_status);
  755. } else if(dz->process == SPECFRAC) {
  756. if(dz->wordstor!=NULL)
  757. free_wordstors(dz);
  758. dz->all_words = 0;
  759. if((exit_status = store_filename((*cmdline)[0],dz))<0)
  760. return(exit_status);
  761. }
  762. (*cmdline)++;
  763. (*cmdlinecnt)--;
  764. return(FINISHED);
  765. }
  766. /***************************** CREATE_NEXT_OUTFILE **************************/
  767. int create_next_outfile(dataptr dz)
  768. {
  769. int exit_status, len;
  770. char *filename = NULL;
  771. dz->itemcnt++;
  772. len = strlen(dz->wordstor[0]) + 5;
  773. if((filename = (char *)malloc(len))==NULL) {
  774. sprintf(errstr,"create_next_outfile NO MEMORY\n");
  775. return(MEMORY_ERROR);
  776. }
  777. strcpy(filename,dz->wordstor[0]);
  778. insert_newnumber_at_filename_end(filename,dz->itemcnt,1);
  779. strcpy(dz->outfilename,filename);
  780. if((exit_status = create_sized_outfile(filename,dz))<0)
  781. return(exit_status);
  782. return(FINISHED);
  783. }
  784. /***************************** INSERT_NEWNUMBER_AT_FILENAME_END **************************/
  785. void insert_newnumber_at_filename_end(char *filename,int num,int overwrite_last_char)
  786. /* FUNCTIONS ASSUMES ENOUGH SPACE IS ALLOCATED !! */
  787. {
  788. char *p;
  789. char ext[64];
  790. p = filename + strlen(filename) - 1;
  791. while(p > filename) {
  792. if(*p == '/' || *p == '\\' || *p == ':') {
  793. p = filename;
  794. break;
  795. }
  796. if(*p == '.') {
  797. strcpy(ext,p);
  798. if(overwrite_last_char)
  799. p--;
  800. sprintf(p,"%d",num);
  801. strcat(filename,ext);
  802. return;
  803. }
  804. p--;
  805. }
  806. if(p == filename) {
  807. p += strlen(filename);
  808. if(overwrite_last_char)
  809. p--;
  810. sprintf(p,"%d",num);
  811. }
  812. }
  813. /***************************** ESTABLISH_APPLICATION **************************/
  814. int establish_application(dataptr dz)
  815. {
  816. aplptr ap;
  817. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  818. sprintf(errstr,"establish_application()\n");
  819. return(MEMORY_ERROR);
  820. }
  821. ap = dz->application;
  822. memset((char *)ap,0,sizeof(struct applic));
  823. return(FINISHED);
  824. }
  825. /************************* INITIALISE_VFLAGS *************************/
  826. int initialise_vflags(dataptr dz)
  827. {
  828. int n;
  829. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  830. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  831. return(MEMORY_ERROR);
  832. }
  833. for(n=0;n<dz->application->vflag_cnt;n++)
  834. dz->vflag[n] = FALSE;
  835. return FINISHED;
  836. }
  837. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  838. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  839. {
  840. int n;
  841. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  842. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  843. return(MEMORY_ERROR);
  844. }
  845. for(n=0;n<tipc;n++)
  846. ap->default_val[n] = 0.0;
  847. return(FINISHED);
  848. }
  849. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  850. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  851. {
  852. int n;
  853. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  854. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  855. return(MEMORY_ERROR);
  856. }
  857. for(n=0;n<tipc;n++)
  858. dz->is_active[n] = (char)0;
  859. return(FINISHED);
  860. }
  861. /************************* SETUP_THE_APPLICATION *******************/
  862. int setup_the_application(dataptr dz)
  863. {
  864. int exit_status;
  865. aplptr ap;
  866. if((exit_status = establish_application(dz))<0) // GLOBAL
  867. return(FAILED);
  868. ap = dz->application;
  869. // SEE parstruct FOR EXPLANATION of next 2 functions
  870. switch(dz->process) {
  871. case(SPEC_REMOVE):
  872. if((exit_status = set_param_data(ap,0 ,4,4,"dddD" ))<0)
  873. return(FAILED);
  874. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  875. return(FAILED);
  876. // set_legal_infile_structure -->
  877. dz->has_otherfile = FALSE;
  878. // assign_process_logic -->
  879. dz->input_data_type = ANALFILE_ONLY;
  880. dz->process_type = EQUAL_ANALFILE;
  881. dz->outfiletype = ANALFILE_OUT;
  882. break;
  883. case(SPECTRACT):
  884. case(SPECLEAN):
  885. if((exit_status = set_param_data(ap,0 ,2,2,"dd" ))<0)
  886. return(FAILED);
  887. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  888. return(FAILED);
  889. // set_legal_infile_structure -->
  890. dz->has_otherfile = FALSE;
  891. // assign_process_logic -->
  892. dz->input_data_type = TWO_ANALFILES;
  893. dz->process_type = EQUAL_ANALFILE;
  894. dz->outfiletype = ANALFILE_OUT;
  895. break;
  896. case(SPECSLICE):
  897. switch(dz->mode) {
  898. case(0):
  899. if((exit_status = set_param_data(ap,0 ,2,2,"iI" ))<0)
  900. return(FAILED);
  901. break;
  902. case(1):
  903. case(2):
  904. if((exit_status = set_param_data(ap,0 ,2,2,"iD" ))<0)
  905. return(FAILED);
  906. break;
  907. case(3):
  908. if((exit_status = set_param_data(ap,P_BRK_DATA ,0,0,"" ))<0)
  909. return(FAILED);
  910. break;
  911. case(4):
  912. if((exit_status = set_param_data(ap,0 ,1,1,"D" ))<0)
  913. return(FAILED);
  914. break;
  915. }
  916. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  917. return(FAILED);
  918. // set_legal_infile_structure -->
  919. dz->has_otherfile = FALSE;
  920. // assign_process_logic -->
  921. dz->input_data_type = ANALFILE_ONLY;
  922. dz->process_type = EQUAL_ANALFILE;
  923. dz->outfiletype = ANALFILE_OUT;
  924. break;
  925. case(SPECRAND):
  926. if((exit_status = set_param_data(ap,0 ,0,0,""))<0)
  927. return(FAILED);
  928. if((exit_status = set_vflgs(ap,"tg",2,"Di","",0,0,""))<0)
  929. return(FAILED);
  930. // set_legal_infile_structure -->
  931. dz->has_otherfile = FALSE;
  932. // assign_process_logic -->
  933. dz->input_data_type = ANALFILE_ONLY;
  934. dz->process_type = EQUAL_ANALFILE;
  935. dz->outfiletype = ANALFILE_OUT;
  936. break;
  937. case(SPECSQZ):
  938. if((exit_status = set_param_data(ap,0 ,2,2,"DD"))<0)
  939. return(FAILED);
  940. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  941. return(FAILED);
  942. // set_legal_infile_structure -->
  943. dz->has_otherfile = FALSE;
  944. // assign_process_logic -->
  945. dz->input_data_type = ANALFILE_ONLY;
  946. dz->process_type = EQUAL_ANALFILE;
  947. dz->outfiletype = ANALFILE_OUT;
  948. break;
  949. case(SPECEX):
  950. if((exit_status = set_param_data(ap,0 ,3,3,"ddd"))<0)
  951. return(FAILED);
  952. if((exit_status = set_vflgs(ap,"w",1,"i","se",2,0,"00"))<0)
  953. return(FAILED);
  954. // set_legal_infile_structure -->
  955. dz->has_otherfile = FALSE;
  956. // assign_process_logic -->
  957. dz->input_data_type = ANALFILE_ONLY;
  958. dz->process_type = BIG_ANALFILE;
  959. dz->outfiletype = ANALFILE_OUT;
  960. break;
  961. case(TRANSPART):
  962. if((exit_status = set_param_data(ap,0 ,3,3,"DDd"))<0)
  963. return(FAILED);
  964. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  965. return(FAILED);
  966. // set_legal_infile_structure -->
  967. dz->has_otherfile = FALSE;
  968. // assign_process_logic -->
  969. dz->input_data_type = ANALFILE_ONLY;
  970. dz->process_type = EQUAL_ANALFILE;
  971. dz->outfiletype = ANALFILE_OUT;
  972. break;
  973. case(SPECINVNU):
  974. if((exit_status = set_param_data(ap,0 ,4,4,"dddd"))<0)
  975. return(FAILED);
  976. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  977. return(FAILED);
  978. // set_legal_infile_structure -->
  979. dz->has_otherfile = FALSE;
  980. // assign_process_logic -->
  981. dz->input_data_type = ANALFILE_ONLY;
  982. dz->process_type = EQUAL_ANALFILE;
  983. dz->outfiletype = ANALFILE_OUT;
  984. break;
  985. case(SPECCONV):
  986. if((exit_status = set_param_data(ap,0 ,1,1,"d"))<0)
  987. return(FAILED);
  988. if(dz->mode == 1) {
  989. if((exit_status = set_vflgs(ap,"d",1,"i","p",1,0,""))<0)
  990. return(FAILED);
  991. } else {
  992. if((exit_status = set_vflgs(ap,"d",1,"i","",0,0,""))<0)
  993. return(FAILED);
  994. }
  995. // set_legal_infile_structure -->
  996. dz->has_otherfile = FALSE;
  997. // assign_process_logic -->
  998. switch(dz->mode) {
  999. case(0):
  1000. dz->input_data_type = ANALFILE_ONLY;
  1001. dz->process_type = EQUAL_ANALFILE;
  1002. break;
  1003. case(1):
  1004. dz->input_data_type = TWO_ANALFILES;
  1005. dz->process_type = BIG_ANALFILE;
  1006. break;
  1007. }
  1008. dz->outfiletype = ANALFILE_OUT;
  1009. break;
  1010. case(SPECSND):
  1011. if((exit_status = set_param_data(ap,0 ,2,2,"ii"))<0)
  1012. return(FAILED);
  1013. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  1014. return(FAILED);
  1015. // set_legal_infile_structure -->
  1016. dz->has_otherfile = FALSE;
  1017. // assign_process_logic -->
  1018. dz->input_data_type = ANALFILE_ONLY;
  1019. dz->process_type = UNEQUAL_SNDFILE;
  1020. dz->outfiletype = SNDFILE_OUT;
  1021. break;
  1022. case(SPECFRAC):
  1023. if((exit_status = set_param_data(ap,0 ,1,1,"i"))<0)
  1024. return(FAILED);
  1025. if((exit_status = set_vflgs(ap,"",0,"","i",1,0,""))<0)
  1026. return(FAILED);
  1027. // set_legal_infile_structure -->
  1028. dz->has_otherfile = FALSE;
  1029. // assign_process_logic -->
  1030. dz->input_data_type = ANALFILE_ONLY;
  1031. dz->process_type = OTHER_PROCESS;
  1032. dz->outfiletype = NO_OUTPUTFILE;
  1033. break;
  1034. }
  1035. return application_init(dz); //GLOBAL
  1036. }
  1037. /************************* PARSE_INFILE_AND_CHECK_TYPE *******************/
  1038. int parse_infile_and_check_type(char **cmdline,dataptr dz)
  1039. {
  1040. int exit_status;
  1041. infileptr infile_info;
  1042. if(!sloom) {
  1043. if((infile_info = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  1044. sprintf(errstr,"INSUFFICIENT MEMORY for infile structure to test file data.");
  1045. return(MEMORY_ERROR);
  1046. } else if((exit_status = cdparse(cmdline[0],infile_info))<0) {
  1047. sprintf(errstr,"Failed tp parse input file %s\n",cmdline[0]);
  1048. return(PROGRAM_ERROR);
  1049. } else if(infile_info->filetype != ANALFILE) {
  1050. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  1051. return(DATA_ERROR);
  1052. } else if((exit_status = copy_parse_info_to_main_structure(infile_info,dz))<0) {
  1053. sprintf(errstr,"Failed to copy file parsing information\n");
  1054. return(PROGRAM_ERROR);
  1055. }
  1056. free(infile_info);
  1057. }
  1058. dz->clength = dz->wanted / 2;
  1059. dz->chwidth = dz->nyquist/(double)(dz->clength-1);
  1060. dz->halfchwidth = dz->chwidth/2.0;
  1061. return(FINISHED);
  1062. }
  1063. /************************* SETUP_THE_PARAM_RANGES_AND_DEFAULTS *******************/
  1064. int setup_the_param_ranges_and_defaults(dataptr dz)
  1065. {
  1066. int exit_status;
  1067. aplptr ap = dz->application;
  1068. // set_param_ranges()
  1069. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  1070. // NB total_input_param_cnt is > 0 !!!s
  1071. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  1072. return(FAILED);
  1073. // get_param_ranges()
  1074. switch(dz->process) {
  1075. case(SPEC_REMOVE):
  1076. ap->lo[0] = MIDIMIN;
  1077. ap->hi[0] = MIDIMAX;
  1078. ap->default_val[0] = 60;
  1079. ap->lo[1] = MIDIMIN;
  1080. ap->hi[1] = MIDIMAX;
  1081. ap->default_val[1] = 60;
  1082. ap->lo[2] = 0;
  1083. ap->hi[2] = dz->nyquist;
  1084. ap->default_val[2] = 6000.0;
  1085. ap->lo[3] = 0.0;
  1086. ap->hi[3] = 1.0;
  1087. ap->default_val[3] = 1.0;
  1088. dz->maxmode = 2;
  1089. break;
  1090. case(SPECLEAN):
  1091. case(SPECTRACT):
  1092. ap->lo[0] = 0.0;
  1093. ap->hi[0] = 1000.0;
  1094. ap->default_val[0] = dz->frametime * 8.0 * SECS_TO_MS;
  1095. ap->lo[1] = 1.0;
  1096. ap->hi[1] = CL_MAX_GAIN;
  1097. ap->default_val[1] = DEFAULT_NOISEGAIN;
  1098. dz->maxmode = 0;
  1099. break;
  1100. case(SPECSLICE):
  1101. switch(dz->mode) {
  1102. case(0):
  1103. ap->lo[0] = 2;
  1104. ap->hi[0] = dz->clength/2;
  1105. ap->default_val[0] = 2;
  1106. ap->lo[1] = 1;
  1107. ap->hi[1] = dz->clength/2;
  1108. ap->default_val[1] = 1;
  1109. break;
  1110. case(1):
  1111. ap->lo[0] = 2;
  1112. ap->hi[0] = dz->clength/2;
  1113. ap->default_val[0] = 2;
  1114. ap->lo[1] = dz->chwidth;
  1115. ap->hi[1] = dz->nyquist/2.0;
  1116. ap->default_val[1] = dz->chwidth;
  1117. break;
  1118. case(2):
  1119. ap->lo[0] = 2;
  1120. ap->hi[0] = dz->clength/2;
  1121. ap->default_val[0] = 2;
  1122. ap->lo[1] = 0.5;
  1123. ap->hi[1] = (LOG2(dz->nyquist/dz->chwidth)/2.0) * SEMITONES_PER_OCTAVE;
  1124. ap->default_val[1] = SEMITONES_PER_OCTAVE;
  1125. break;
  1126. case(4):
  1127. ap->lo[0] = dz->chwidth;
  1128. ap->hi[0] = dz->nyquist - dz->chwidth;
  1129. ap->default_val[0] = dz->nyquist/2;
  1130. break;
  1131. }
  1132. dz->maxmode = 4;
  1133. break;
  1134. case(SPECRAND):
  1135. ap->lo[0] = dz->frametime * 2;
  1136. ap->hi[0] = dz->duration;
  1137. ap->default_val[0] = dz->duration;
  1138. ap->lo[1] = 1;
  1139. ap->hi[1] = dz->wlength/2;
  1140. ap->default_val[1] = 1;
  1141. dz->maxmode = 0;
  1142. break;
  1143. case(SPECSQZ):
  1144. ap->lo[0] = 0;
  1145. ap->hi[0] = dz->nyquist;
  1146. ap->default_val[0] = 440.0;
  1147. ap->lo[1] = 1.0/(double)dz->clength;
  1148. ap->hi[1] = 1;
  1149. ap->default_val[1] = 0.5;
  1150. dz->maxmode = 0;
  1151. break;
  1152. case(SPECEX):
  1153. ap->lo[SPEX_TIM] = 0;
  1154. ap->hi[SPEX_TIM] = dz->duration;
  1155. ap->default_val[SPEX_TIM] = 0;
  1156. ap->lo[SPEX_DUR] = dz->frametime * 3;
  1157. ap->hi[SPEX_DUR] = dz->duration;
  1158. ap->default_val[SPEX_DUR] = dz->frametime * 3;
  1159. ap->lo[SPEX_STR] = 2.0;
  1160. ap->hi[SPEX_STR] = 32767.0;
  1161. ap->default_val[SPEX_STR] = 64.0;
  1162. ap->lo[SPEX_WIN] = 1;
  1163. ap->hi[SPEX_WIN] = 8;
  1164. ap->default_val[SPEX_WIN] = 1;
  1165. dz->maxmode = 0;
  1166. break;
  1167. case(TRANSPART):
  1168. switch(dz->mode) {
  1169. case(0): // fall thro
  1170. case(1):
  1171. case(2):
  1172. case(3):
  1173. ap->lo[0] = -48;
  1174. ap->hi[0] = 48;
  1175. ap->default_val[0] = 12;
  1176. break;
  1177. case(4): // fall thro
  1178. case(5):
  1179. case(6):
  1180. case(7):
  1181. ap->lo[0] = -dz->nyquist/4;
  1182. ap->hi[0] = dz->nyquist/4;
  1183. ap->default_val[0] = 100;
  1184. break;
  1185. }
  1186. ap->lo[1] = 5.0;
  1187. ap->hi[1] = dz->nyquist/2.0;
  1188. ap->default_val[1] = 440;
  1189. ap->lo[2] = 0.1;
  1190. ap->hi[2] = 1.0;
  1191. ap->default_val[2] = 1.0;
  1192. dz->maxmode = 8;
  1193. break;
  1194. case(SPECINVNU):
  1195. ap->lo[0] = 0.0;
  1196. ap->hi[0] = dz->nyquist/2;
  1197. ap->default_val[0] = 0.0;
  1198. ap->lo[1] = 100.0;
  1199. ap->hi[1] = dz->nyquist;
  1200. ap->default_val[1] = dz->nyquist;
  1201. ap->lo[2] = 0;
  1202. ap->hi[2] = dz->nyquist;
  1203. ap->default_val[2] = 4;
  1204. ap->lo[3] = 0.1;
  1205. ap->hi[3] = 1.0;
  1206. ap->default_val[3] = 1.0;
  1207. dz->maxmode = 0;
  1208. break;
  1209. case(SPECCONV):
  1210. ap->lo[0] = 0.1;
  1211. ap->hi[0] = 10.0;
  1212. ap->default_val[0] = 1.0;
  1213. ap->lo[1] = 1;
  1214. if(dz->mode == 0)
  1215. ap->hi[1] = 10;
  1216. else
  1217. ap->hi[1] = 2;
  1218. ap->default_val[1] = 1;
  1219. dz->maxmode = 2;
  1220. break;
  1221. case(SPECSND):
  1222. ap->lo[0] = 0;
  1223. ap->hi[0] = 8;
  1224. ap->default_val[0] = 0;
  1225. ap->lo[1] = 1;
  1226. ap->hi[1] = 8;
  1227. ap->default_val[1] = 1;
  1228. dz->maxmode = 0;
  1229. break;
  1230. case(SPECFRAC):
  1231. switch(dz->mode) {
  1232. case(6): // fall thro
  1233. case(8):
  1234. ap->lo[0] = 2;
  1235. break;
  1236. default:
  1237. ap->lo[0] = 1;
  1238. break;
  1239. }
  1240. ap->hi[0] = 100;
  1241. ap->default_val[0] = 8;
  1242. dz->maxmode = 9;
  1243. break;
  1244. }
  1245. if(!sloom)
  1246. put_default_vals_in_all_params(dz);
  1247. return(FINISHED);
  1248. }
  1249. /********************************* PARSE_SLOOM_DATA *********************************/
  1250. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  1251. {
  1252. int exit_status;
  1253. int cnt = 1, infilecnt;
  1254. int filesize, insams, inbrksize;
  1255. double dummy;
  1256. int true_cnt = 0;
  1257. aplptr ap;
  1258. while(cnt<=PRE_CMDLINE_DATACNT) {
  1259. if(cnt > argc) {
  1260. sprintf(errstr,"Insufficient data sent from TK\n");
  1261. return(DATA_ERROR);
  1262. }
  1263. switch(cnt) {
  1264. case(1):
  1265. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  1266. sprintf(errstr,"Cannot read process no. sent from TK\n");
  1267. return(DATA_ERROR);
  1268. }
  1269. break;
  1270. case(2):
  1271. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  1272. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  1273. return(DATA_ERROR);
  1274. }
  1275. if(dz->mode > 0)
  1276. dz->mode--;
  1277. //setup_particular_application() =
  1278. if((exit_status = setup_the_application(dz))<0)
  1279. return(exit_status);
  1280. ap = dz->application;
  1281. break;
  1282. case(3):
  1283. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  1284. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  1285. return(DATA_ERROR);
  1286. }
  1287. if(infilecnt < 1) {
  1288. true_cnt = cnt + 1;
  1289. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  1290. }
  1291. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  1292. return(exit_status);
  1293. break;
  1294. case(INPUT_FILETYPE+4):
  1295. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  1296. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  1297. return(DATA_ERROR);
  1298. }
  1299. break;
  1300. case(INPUT_FILESIZE+4):
  1301. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  1302. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  1303. return(DATA_ERROR);
  1304. }
  1305. dz->insams[0] = filesize;
  1306. break;
  1307. case(INPUT_INSAMS+4):
  1308. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  1309. sprintf(errstr,"Cannot read insams sent from TK\n");
  1310. return(DATA_ERROR);
  1311. }
  1312. dz->insams[0] = insams;
  1313. break;
  1314. case(INPUT_SRATE+4):
  1315. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  1316. sprintf(errstr,"Cannot read srate sent from TK\n");
  1317. return(DATA_ERROR);
  1318. }
  1319. break;
  1320. case(INPUT_CHANNELS+4):
  1321. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  1322. sprintf(errstr,"Cannot read channels sent from TK\n");
  1323. return(DATA_ERROR);
  1324. }
  1325. break;
  1326. case(INPUT_STYPE+4):
  1327. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  1328. sprintf(errstr,"Cannot read stype sent from TK\n");
  1329. return(DATA_ERROR);
  1330. }
  1331. break;
  1332. case(INPUT_ORIGSTYPE+4):
  1333. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  1334. sprintf(errstr,"Cannot read origstype sent from TK\n");
  1335. return(DATA_ERROR);
  1336. }
  1337. break;
  1338. case(INPUT_ORIGRATE+4):
  1339. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  1340. sprintf(errstr,"Cannot read origrate sent from TK\n");
  1341. return(DATA_ERROR);
  1342. }
  1343. break;
  1344. case(INPUT_MLEN+4):
  1345. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  1346. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  1347. return(DATA_ERROR);
  1348. }
  1349. break;
  1350. case(INPUT_DFAC+4):
  1351. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  1352. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  1353. return(DATA_ERROR);
  1354. }
  1355. break;
  1356. case(INPUT_ORIGCHANS+4):
  1357. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  1358. sprintf(errstr,"Cannot read origchans sent from TK\n");
  1359. return(DATA_ERROR);
  1360. }
  1361. break;
  1362. case(INPUT_SPECENVCNT+4):
  1363. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  1364. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  1365. return(DATA_ERROR);
  1366. }
  1367. dz->specenvcnt = dz->infile->specenvcnt;
  1368. break;
  1369. case(INPUT_WANTED+4):
  1370. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  1371. sprintf(errstr,"Cannot read wanted sent from TK\n");
  1372. return(DATA_ERROR);
  1373. }
  1374. break;
  1375. case(INPUT_WLENGTH+4):
  1376. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  1377. sprintf(errstr,"Cannot read wlength sent from TK\n");
  1378. return(DATA_ERROR);
  1379. }
  1380. break;
  1381. case(INPUT_OUT_CHANS+4):
  1382. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  1383. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  1384. return(DATA_ERROR);
  1385. }
  1386. break;
  1387. /* RWD these chanegs to samps - tk will have to deal with that! */
  1388. case(INPUT_DESCRIPTOR_BYTES+4):
  1389. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  1390. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  1391. return(DATA_ERROR);
  1392. }
  1393. break;
  1394. case(INPUT_IS_TRANSPOS+4):
  1395. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  1396. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  1397. return(DATA_ERROR);
  1398. }
  1399. break;
  1400. case(INPUT_COULD_BE_TRANSPOS+4):
  1401. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  1402. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  1403. return(DATA_ERROR);
  1404. }
  1405. break;
  1406. case(INPUT_COULD_BE_PITCH+4):
  1407. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  1408. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  1409. return(DATA_ERROR);
  1410. }
  1411. break;
  1412. case(INPUT_DIFFERENT_SRATES+4):
  1413. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  1414. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  1415. return(DATA_ERROR);
  1416. }
  1417. break;
  1418. case(INPUT_DUPLICATE_SNDS+4):
  1419. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  1420. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  1421. return(DATA_ERROR);
  1422. }
  1423. break;
  1424. case(INPUT_BRKSIZE+4):
  1425. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  1426. sprintf(errstr,"Cannot read brksize sent from TK\n");
  1427. return(DATA_ERROR);
  1428. }
  1429. if(inbrksize > 0) {
  1430. switch(dz->input_data_type) {
  1431. case(WORDLIST_ONLY):
  1432. break;
  1433. case(PITCH_AND_PITCH):
  1434. case(PITCH_AND_TRANSPOS):
  1435. case(TRANSPOS_AND_TRANSPOS):
  1436. dz->tempsize = inbrksize;
  1437. break;
  1438. case(BRKFILES_ONLY):
  1439. case(UNRANGED_BRKFILE_ONLY):
  1440. case(DB_BRKFILES_ONLY):
  1441. case(ALL_FILES):
  1442. case(ANY_NUMBER_OF_ANY_FILES):
  1443. if(dz->extrabrkno < 0) {
  1444. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  1445. return(DATA_ERROR);
  1446. }
  1447. if(dz->brksize == NULL) {
  1448. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  1449. return(PROGRAM_ERROR);
  1450. }
  1451. dz->brksize[dz->extrabrkno] = inbrksize;
  1452. break;
  1453. default:
  1454. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  1455. dz->input_data_type);
  1456. return(PROGRAM_ERROR);
  1457. }
  1458. break;
  1459. }
  1460. break;
  1461. case(INPUT_NUMSIZE+4):
  1462. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  1463. sprintf(errstr,"Cannot read numsize sent from TK\n");
  1464. return(DATA_ERROR);
  1465. }
  1466. break;
  1467. case(INPUT_LINECNT+4):
  1468. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  1469. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  1470. return(DATA_ERROR);
  1471. }
  1472. break;
  1473. case(INPUT_ALL_WORDS+4):
  1474. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  1475. sprintf(errstr,"Cannot read all_words sent from TK\n");
  1476. return(DATA_ERROR);
  1477. }
  1478. break;
  1479. case(INPUT_ARATE+4):
  1480. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  1481. sprintf(errstr,"Cannot read arate sent from TK\n");
  1482. return(DATA_ERROR);
  1483. }
  1484. break;
  1485. case(INPUT_FRAMETIME+4):
  1486. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  1487. sprintf(errstr,"Cannot read frametime sent from TK\n");
  1488. return(DATA_ERROR);
  1489. }
  1490. dz->frametime = (float)dummy;
  1491. break;
  1492. case(INPUT_WINDOW_SIZE+4):
  1493. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  1494. sprintf(errstr,"Cannot read window_size sent from TK\n");
  1495. return(DATA_ERROR);
  1496. }
  1497. break;
  1498. case(INPUT_NYQUIST+4):
  1499. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  1500. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  1501. return(DATA_ERROR);
  1502. }
  1503. break;
  1504. case(INPUT_DURATION+4):
  1505. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  1506. sprintf(errstr,"Cannot read duration sent from TK\n");
  1507. return(DATA_ERROR);
  1508. }
  1509. break;
  1510. case(INPUT_MINBRK+4):
  1511. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  1512. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  1513. return(DATA_ERROR);
  1514. }
  1515. break;
  1516. case(INPUT_MAXBRK+4):
  1517. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  1518. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  1519. return(DATA_ERROR);
  1520. }
  1521. break;
  1522. case(INPUT_MINNUM+4):
  1523. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  1524. sprintf(errstr,"Cannot read minnum sent from TK\n");
  1525. return(DATA_ERROR);
  1526. }
  1527. break;
  1528. case(INPUT_MAXNUM+4):
  1529. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  1530. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  1531. return(DATA_ERROR);
  1532. }
  1533. break;
  1534. default:
  1535. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  1536. return(PROGRAM_ERROR);
  1537. }
  1538. cnt++;
  1539. }
  1540. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  1541. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  1542. return(DATA_ERROR);
  1543. }
  1544. if(true_cnt)
  1545. cnt = true_cnt;
  1546. *cmdlinecnt = 0;
  1547. while(cnt < argc) {
  1548. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  1549. return(exit_status);
  1550. cnt++;
  1551. }
  1552. return(FINISHED);
  1553. }
  1554. /********************************* GET_TK_CMDLINE_WORD *********************************/
  1555. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  1556. {
  1557. if(*cmdlinecnt==0) {
  1558. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  1559. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  1560. return(MEMORY_ERROR);
  1561. }
  1562. } else {
  1563. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  1564. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  1565. return(MEMORY_ERROR);
  1566. }
  1567. }
  1568. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  1569. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  1570. return(MEMORY_ERROR);
  1571. }
  1572. strcpy((*cmdline)[*cmdlinecnt],q);
  1573. (*cmdlinecnt)++;
  1574. return(FINISHED);
  1575. }
  1576. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  1577. int assign_file_data_storage(int infilecnt,dataptr dz)
  1578. {
  1579. int exit_status;
  1580. int no_sndfile_system_files = FALSE;
  1581. dz->infilecnt = infilecnt;
  1582. if((exit_status = allocate_filespace(dz))<0)
  1583. return(exit_status);
  1584. if(no_sndfile_system_files)
  1585. dz->infilecnt = 0;
  1586. return(FINISHED);
  1587. }
  1588. /*********************** CHECK_THE_PARAM_VALIDITY_AND_CONSISTENCY *********************/
  1589. int check_the_param_validity_and_consistency(dataptr dz)
  1590. {
  1591. int n, m, cnt, exit_status;
  1592. double lo,hi,lostep,histep,semitonespan, maxval = 0.0;
  1593. switch(dz->process) {
  1594. case(SPEC_REMOVE):
  1595. dz->param[0] = miditohz(dz->param[0]);
  1596. dz->param[1] = miditohz(dz->param[1]);
  1597. lo = min(dz->param[0],dz->param[1]);
  1598. if((dz->brksize[3] == 0) && flteq(dz->param[3],0.0)) {
  1599. sprintf(errstr,"Attenuation is zero: spectrum will not be changed.\n");
  1600. return(DATA_ERROR);
  1601. }
  1602. cnt = 0;
  1603. hi = lo;
  1604. while(hi <= dz->param[2]) {
  1605. cnt++;
  1606. hi += lo;
  1607. }
  1608. if(cnt == 0) {
  1609. sprintf(errstr,"Upper search limit (%lf) means there are no pitches to search for.\n",dz->param[2]);
  1610. return(MEMORY_ERROR);
  1611. }
  1612. hi = max(dz->param[0],dz->param[1]);
  1613. dz->zeroset = 0;
  1614. if(lo * 2.0 <= hi) {
  1615. fprintf(stdout,"WARNING: Pitchrange of octave or more.\n");
  1616. fprintf(stdout,"WARNING: Will eliminate entire spectrum between lower pitch and %lf Hz\n",dz->param[2]);
  1617. fflush(stdout);
  1618. dz->zeroset = 1;
  1619. dz->param[0] = lo;
  1620. } else {
  1621. if((dz->parray[0] = (double *)malloc(cnt * sizeof(double)))==NULL) {
  1622. sprintf(errstr,"No memory to store 1st set of harmonics.\n");
  1623. return(MEMORY_ERROR);
  1624. }
  1625. if((dz->parray[1] = (double *)malloc(cnt * sizeof(double)))==NULL) {
  1626. sprintf(errstr,"No memory to store 2nd set of harmonics.\n");
  1627. return(MEMORY_ERROR);
  1628. }
  1629. lostep = lo;
  1630. histep = hi;
  1631. for(n = 0;n<cnt;n++) {
  1632. dz->parray[0][n] = lo;
  1633. dz->parray[1][n] = hi;
  1634. lo += lostep;
  1635. hi += histep;
  1636. }
  1637. dz->itemcnt = cnt;
  1638. }
  1639. break;
  1640. case(SPECLEAN):
  1641. case(SPECTRACT):
  1642. dz->iparam[0] = (int)cdp_round((dz->param[0] * MS_TO_SECS)/dz->frametime);
  1643. dz->iparam[0] = max(dz->iparam[0],1);
  1644. n = dz->insams[0]/dz->wanted;
  1645. if(n < dz->iparam[0] + 1) {
  1646. sprintf(errstr,"File is too short for the 'persist' parameter used.\n");
  1647. return(GOAL_FAILED);
  1648. }
  1649. break;
  1650. case(SPECSLICE):
  1651. if(dz->mode < 4) {
  1652. if((exit_status = get_maxvalue(1,&maxval,dz)) < 0)
  1653. return(exit_status);
  1654. }
  1655. if(dz->mode == 3) {
  1656. dz->param[0] = (int)(floor(dz->nyquist/maxval));
  1657. break;
  1658. }
  1659. switch(dz->mode) {
  1660. case(0):
  1661. if(dz->param[0] * maxval >= dz->clength) {
  1662. sprintf(errstr,"Insufficient channels to accomodate your parameters.\n");
  1663. return(GOAL_FAILED);
  1664. }
  1665. break;
  1666. case(1):
  1667. if(dz->param[0] * maxval >= dz->nyquist) {
  1668. sprintf(errstr,"Insufficient bandwidth to accomodate your parameters.\n");
  1669. return(GOAL_FAILED);
  1670. }
  1671. break;
  1672. case(2):
  1673. semitonespan = LOG2(dz->nyquist/dz->chwidth) * SEMITONES_PER_OCTAVE;
  1674. if(dz->param[0] * maxval >= semitonespan) {
  1675. sprintf(errstr,"Insufficient bandwidth to accomodate your parameters.\n");
  1676. return(GOAL_FAILED);
  1677. }
  1678. break;
  1679. }
  1680. break;
  1681. case(SPECRAND):
  1682. if(dz->brksize[0]) {
  1683. if((exit_status = get_minvalue_in_brktable(&(dz->param[0]),0,dz))<0)
  1684. return(exit_status);
  1685. }
  1686. dz->iparam[0] = (int)round(dz->param[0]/dz->frametime); // Convert timeframe to window count
  1687. if(dz->iparam[0] < 2)
  1688. dz->iparam[0] = 2;
  1689. if (dz->iparam[1] * 2 >= dz->iparam[0]) {
  1690. sprintf(errstr,"GROUPING TOO LARGE FOR (MINIMUM) TIMEFRAME SPECIFIED : Max approx = %d\n",dz->iparam[0]/2);
  1691. return DATA_ERROR;
  1692. }
  1693. if((dz->iparray[0] = (int *)malloc((dz->wlength + 1) * sizeof(int)))==NULL) {
  1694. sprintf(errstr,"INSUFFICIENT MEMORY for internal integer array 0.\n");
  1695. return(MEMORY_ERROR);
  1696. }
  1697. if((dz->iparray[1] = (int *)malloc(dz->wlength * sizeof(int)))==NULL) {
  1698. sprintf(errstr,"INSUFFICIENT MEMORY for internal integer array 1.\n");
  1699. return(MEMORY_ERROR);
  1700. }
  1701. break;
  1702. case(SPECSQZ):
  1703. // case(SPECSYNC):
  1704. break;
  1705. case(SPECEX):
  1706. histep = dz->duration - dz->param[SPEX_TIM];
  1707. if(dz->param[SPEX_DUR] >= histep) {
  1708. sprintf(errstr,"Duration of portion to be stretched extends beyond end of file.\n");
  1709. return(DATA_ERROR);
  1710. }
  1711. dz->iparam[SPEX_TIM] = (int)round(dz->param[SPEX_TIM]/dz->frametime); // Start window of portion to be stretched
  1712. dz->iparam[SPEX_DUR] = (int)round(dz->param[SPEX_DUR]/dz->frametime); // Number of windows in portion to be stretched
  1713. n = dz->iparam[SPEX_DUR]/dz->iparam[SPEX_WIN]; // Stretch-duration must be a multiple of window-grouping
  1714. dz->iparam[SPEX_DUR] = n * dz->iparam[SPEX_WIN];
  1715. if(dz->iparam[SPEX_DUR] <= dz->iparam[SPEX_WIN]) {
  1716. sprintf(errstr,"Portion to be stretched is too short to use groupings of %d windows.\n",dz->iparam[SPEX_WIN]);
  1717. return(DATA_ERROR);
  1718. }
  1719. break;
  1720. case(TRANSPART):
  1721. if(dz->mode < 4) {
  1722. if(dz->brksize[0]) {
  1723. for(n=0,m=1;n<dz->brksize[0];n++,m+=2)
  1724. dz->brk[0][m] = SEMITONES_AS_RATIO(dz->brk[0][m]);
  1725. } else
  1726. dz->param[0] = SEMITONES_AS_RATIO(dz->param[0]);
  1727. }
  1728. break;
  1729. case(SPECINVNU):
  1730. if(dz->param[1] <= dz->param[0]) {
  1731. sprintf(errstr,"top of inversion-area must be ABOVE bottom of inversion-area.\n");
  1732. return DATA_ERROR;
  1733. }
  1734. lostep = dz->param[1] - dz->param[0];
  1735. n = (int)round(lostep/dz->chwidth);
  1736. if(n < 2) {
  1737. sprintf(errstr,"Frq range of inversion-area (%lf) too small for analfile's windowsize (%lf).\n",lostep,dz->chwidth);
  1738. return DATA_ERROR;
  1739. }
  1740. if(dz->param[2] < dz->param[0]) {
  1741. sprintf(errstr,"top of peak-search-area must be within inversion-area.\n");
  1742. return DATA_ERROR;
  1743. }
  1744. if(dz->param[2] > dz->param[0] + lostep/2) {
  1745. sprintf(errstr,"top of peak-search-area must not be more than halfway through inversion-area.\n");
  1746. return DATA_ERROR;
  1747. }
  1748. break;
  1749. case(SPECCONV):
  1750. if(dz->mode == 1) {
  1751. if(dz->insams[1] > dz->insams[0]) {
  1752. sprintf(errstr,"Wrong number of input files : Cannot proceed.\n");
  1753. return DATA_ERROR;
  1754. }
  1755. }
  1756. break;
  1757. case(SPECSND):
  1758. if(dz->iparam[1] <= dz->iparam[0]) {
  1759. sprintf(errstr,"Range of transpositions Zero or inverted.\n");
  1760. return(DATA_ERROR);
  1761. }
  1762. break;
  1763. case(SPECFRAC):
  1764. if((exit_status = check_fractal_param_validity_and_consistency(dz))<0)
  1765. return(exit_status);
  1766. break;
  1767. }
  1768. return FINISHED;
  1769. }
  1770. /************************* redundant functions: to ensure libs compile OK *******************/
  1771. int assign_process_logic(dataptr dz)
  1772. {
  1773. return(FINISHED);
  1774. }
  1775. void set_legal_infile_structure(dataptr dz)
  1776. {}
  1777. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  1778. {
  1779. return(FINISHED);
  1780. }
  1781. int setup_internal_arrays_and_array_pointers(dataptr dz)
  1782. {
  1783. return(FINISHED);
  1784. }
  1785. int establish_bufptrs_and_extra_buffers(dataptr dz)
  1786. {
  1787. return(FINISHED);
  1788. }
  1789. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1790. {
  1791. return(FINISHED);
  1792. }
  1793. int read_special_data(char *str,dataptr dz)
  1794. {
  1795. return(FINISHED);
  1796. }
  1797. /********************************************************************************************/
  1798. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1799. {
  1800. if (!strcmp(prog_identifier_from_cmdline,"remove")) dz->process = SPEC_REMOVE;
  1801. else if (!strcmp(prog_identifier_from_cmdline,"clean")) dz->process = SPECLEAN;
  1802. else if (!strcmp(prog_identifier_from_cmdline,"subtract")) dz->process = SPECTRACT;
  1803. else if (!strcmp(prog_identifier_from_cmdline,"slice")) dz->process = SPECSLICE;
  1804. else if (!strcmp(prog_identifier_from_cmdline,"rand")) dz->process = SPECRAND;
  1805. else if (!strcmp(prog_identifier_from_cmdline,"squeeze")) dz->process = SPECSQZ;
  1806. // else if (!strcmp(prog_identifier_from_cmdline,"sync")) dz->process = SPECSYNC;
  1807. else if (!strcmp(prog_identifier_from_cmdline,"extend")) dz->process = SPECEX;
  1808. else if (!strcmp(prog_identifier_from_cmdline,"transpart")) dz->process = TRANSPART;
  1809. else if (!strcmp(prog_identifier_from_cmdline,"invert")) dz->process = SPECINVNU;
  1810. else if (!strcmp(prog_identifier_from_cmdline,"convolve")) dz->process = SPECCONV;
  1811. else if (!strcmp(prog_identifier_from_cmdline,"tosound")) dz->process = SPECSND;
  1812. else if (!strcmp(prog_identifier_from_cmdline,"fractal")) dz->process = SPECFRAC;
  1813. else {
  1814. sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  1815. return(USAGE_ONLY);
  1816. }
  1817. return(FINISHED);
  1818. }
  1819. /**************************** ALLOCATE_SPECLEAN_BUFFER ******************************/
  1820. int allocate_speclean_buffer(dataptr dz)
  1821. {
  1822. unsigned int buffersize;
  1823. buffersize = dz->wanted * (dz->bptrcnt + 2);
  1824. dz->buflen = dz->wanted;
  1825. if((dz->bigfbuf = (float*) malloc(buffersize * sizeof(float)))==NULL) {
  1826. sprintf(errstr,"INSUFFICIENT MEMORY for sound buffers.\n");
  1827. return(MEMORY_ERROR);
  1828. }
  1829. return(FINISHED);
  1830. }
  1831. /******************************** USAGE1 ********************************/
  1832. int usage1(void)
  1833. {
  1834. fprintf(stderr,
  1835. "\nFURTHER OPERATIONS ON ANALYSIS FILES\n\n"
  1836. "USAGE: specnu NAME (mode) infile(s) outfile parameters: \n"
  1837. "\n"
  1838. "where NAME can be any one of\n"
  1839. "\n"
  1840. "remove clean subtract slice rand squeeze\n\n"
  1841. "extend transpart convolve tosound\n\n"
  1842. "Type 'specnu remove' for more info on specnu remove..ETC.\n");
  1843. return(USAGE_ONLY);
  1844. }
  1845. /******************************** USAGE2 ********************************/
  1846. int usage2(char *str)
  1847. {
  1848. if(!strcmp(str,"remove")) {
  1849. fprintf(stdout,
  1850. "USAGE:\n"
  1851. "specnu remove 1-2 inanalfile outanalfile midimin midimax rangetop atten\n"
  1852. "\n"
  1853. "MODE 1: removes pitch and its harmonics up to a specified frequency limit\n"
  1854. "MODE 2: removes everything else.\n"
  1855. "\n"
  1856. "MIDIMIN minimum pitch to remove (MIDI).\n"
  1857. "MIDIMAX maximum pitch to remove (MIDI).\n"
  1858. "RANGETOP frequency at which search for harmonics stops (Hz).\n"
  1859. "ATTEN attenuation of suppressed components (1 = max, 0 = none).\n"
  1860. "\n"
  1861. "Midi range normally should be small.\n"
  1862. "If range is octave or more, whole spectrum between lower pitch & rangetop\n"
  1863. "will be removed.\n"
  1864. "\n");
  1865. } else if(!strcmp(str,"clean")) {
  1866. fprintf(stdout,
  1867. "USAGE:\n"
  1868. "specnu clean sigfile noisfile outanalfile persist noisgain\n"
  1869. "\n"
  1870. "Eliminate frqbands in 'sigfile' falling below maxlevels found in 'noisfile'\n"
  1871. "\n"
  1872. "PERSIST min-time chan-signal > noise-level, to be retained (Range 0-1000 ms).\n"
  1873. "NOISGAIN multiplies noiselevels in noisfile channels before they are used\n"
  1874. " for comparison with infile signal: (Range 1 - %.0lf).\n"
  1875. "\n"
  1876. "Both input files are analysis files.\n"
  1877. "'noisfil' is a sample of noise (only) from the 'sigfile'.\n"
  1878. "\n",CL_MAX_GAIN);
  1879. } else if(!strcmp(str,"subtract")) {
  1880. fprintf(stdout,
  1881. "USAGE:\n"
  1882. "specnu subtract sigfile noisfile outanalfile persist noisgain\n"
  1883. "\n"
  1884. "Eliminate frqbands in 'sigfile' falling below maxlevels found in 'noisfile'\n"
  1885. "and subtract amplitude of noise in noisfile channels from signal that is passed.\n"
  1886. "\n"
  1887. "PERSIST min-time chan-signal > noise-level, to be retained (Range 0-1000 ms).\n"
  1888. "NOISGAIN multiplies noiselevels in noisfile channels before they are used\n"
  1889. " for comparison with infile signal: (Range 1 - %.0lf).\n"
  1890. "\n"
  1891. "Both input files are analysis files.\n"
  1892. "'noisfil' is a sample of noise (only) from the 'sigfile'.\n"
  1893. "\n",CL_MAX_GAIN);
  1894. } else if(!strcmp(str,"slice")) {
  1895. fprintf(stdout,
  1896. "USAGE:\n"
  1897. "specnu slice 1-3 inanalfile outanalfiles bandcnt chanwidth\n"
  1898. "specnu slice 4 inanalfile outanalfiles pitchdata\n"
  1899. "specnu slice 5 inanalfile outanalfile invertaroundfrq\n"
  1900. "\n"
  1901. "Slices spectrum (frqwise) into mutually exclusive parts, or inverts\n"
  1902. "MODE 1: (moiree slice) -- chanwidth in analysis channels\n"
  1903. "puts alternate (groups of) channels into different slices: e.g.\n"
  1904. "bandcnt 3 chanwidth 1 -> outfil1: 0 3 6... outfil2: 1 4 7... outfil3: 2 5 8 ... \n"
  1905. "bandcnt 2 chanwidth 2 -> outfil1: 0-1 4-5 9-8... outfil2: 2-3 6-7 10-11...\n"
  1906. "(bandcnt must be > 1)\n"
  1907. "MODE 2: (frq band slice) -- chanwidth in Hz\n"
  1908. "puts alternate (groups of) chans into different equal-width frq bands: e.g.\n"
  1909. "(bandcnt can be 1)\n"
  1910. "MODE 3: (pitch band slice) -- chanwidth in semitones\n"
  1911. "puts alternate (groups of) chans into different equal-width pitch bands: e.g.\n"
  1912. "(bandcnt can be 1)\n"
  1913. "MODE 4: (slice by harmonics) -- requires a text datafile of time-frq values\n"
  1914. "(generated by \"repitch getpitch\"). Outputs a file for each harmonic tracked.\n"
  1915. "\n"
  1916. "With outfile \"myname\", produces files \"myname\", \"mynam1\", \"myname2\" etc.\n"
  1917. "\n");
  1918. } else if(!strcmp(str,"rand")) {
  1919. fprintf(stdout,
  1920. "USAGE:\n"
  1921. "specnu rand inanalfile outanalfile [-ttimescale] [-ggrouping]\n"
  1922. "\n"
  1923. "Randomise order of spectral windows.\n"
  1924. "\n"
  1925. "TIMESCALE determines no of windows locally-randomised. (dflt all windows)\n"
  1926. "GROUPING consecutive windows grouped into sets of size \"grouping\".\n"
  1927. " These sets are randomised (default grouping = 1 window per set).\n"
  1928. "\n"
  1929. "\"Timescale\" may vary over time\n"
  1930. "\n");
  1931. } else if(!strcmp(str,"squeeze")) {
  1932. fprintf(stdout,
  1933. "USAGE:\n"
  1934. "specnu squeeze inanalfile outanalfile centrefrq squeeze\n"
  1935. "\n"
  1936. "Squeeze spectrum in frequency range, around a specified centre frq.\n"
  1937. "\n"
  1938. "CENTREFRQ frequency around which frequency data is squeezed.\n"
  1939. "SQUEEZE Amount of squeezing of spectrum (< 1)\n"
  1940. "\n"
  1941. "All parameters may vray over time.\n"
  1942. "\n");
  1943. #ifdef NOTDEF
  1944. /* RWD : process excluded by TW, so needs excluding here too */
  1945. } else if(!strcmp(str,"sync")) {
  1946. fprintf(stdout,
  1947. "USAGE:\n"
  1948. "specnu sync inanalfile outanalfile syncdata\n"
  1949. "\n"
  1950. "SYNCDATA is a textfile containing two columns of times.\n"
  1951. " The times in column 1 are the \"sync-to\" times\n"
  1952. " and the times in column 2, the \"sync-from\" times.\n"
  1953. "\n"
  1954. " The input file is to be timewarped so that the\n"
  1955. " sounds located at the \"sync-from\" times in the input file\n"
  1956. " are moved to the corresponding \"sync-to\" times in the output.\n"
  1957. "\n"
  1958. " A file can be point-to-point synchronised with a 2nd file\n"
  1959. " by listing, in col-1, times in 2nd file which are to be syncd TO,\n"
  1960. " and, listing in col-2 the corresponding times in the infile\n"
  1961. " which must be moved to sync with the those in col-1.\n"
  1962. "\n"
  1963. " Times in both columns must increase,\n"
  1964. " and times in the \"sync-from\" column (2) cannot reach beyond\n"
  1965. " the duration of the input file.\n"
  1966. "\n");
  1967. #endif
  1968. } else if(!strcmp(str,"extend")) {
  1969. fprintf(stdout,
  1970. "USAGE:\n"
  1971. "specnu extend inanalfile outanalfile time dur stretch -wwingroup -s -e\n"
  1972. "\n"
  1973. "Stretch time by repeating, with random perms (groups of) windows.\n"
  1974. "\n"
  1975. "TIME Start time of portion to extend.\n"
  1976. "DUR Duration of portion to extend.\n"
  1977. "STRETCH Time-stretching multiplier.\n"
  1978. "WINGROUP number of windows in groups to rand-permute. Default 1.\n"
  1979. "-s Retain spectrum prior to time-stretched portion.\n"
  1980. "-e Retain spectrum after time-stretched portion.\n"
  1981. "\n");
  1982. } else if(!strcmp(str,"transpart")) {
  1983. fprintf(stdout,
  1984. "USAGE:\n"
  1985. "specnu transpart inanalfile outanalfile 1-4 transpose from gain\n"
  1986. "specnu transpart inanalfile outanalfile 5-8 shift from gain\n"
  1987. "\n"
  1988. "Transpose spectrum by semitones\n"
  1989. "MODES 1 only ABOVE given frequency : retain formants in place.\n"
  1990. "MODES 2 only BELOW given frequency : retain formants in place.\n"
  1991. "MODES 3 only ABOVE given frequency : formants moved.\n"
  1992. "MODES 4 only BELOW given frequency : formants moved.\n"
  1993. "Frequency Shift spectrum in Hz\n"
  1994. "MODES 5 only ABOVE given frequency : retain formants in place.\n"
  1995. "MODES 6 only BELOW given frequency : retain formants in place.\n"
  1996. "MODES 7 only ABOVE given frequency : formants moved.\n"
  1997. "MODES 8 only BELOW given frequency : formants moved.\n"
  1998. "\n"
  1999. "TRANSPOSE Semitone transposition. Range 4 octaves, up or down.\n"
  2000. "SHIFT Frequency shift. Range nyquist/4 up or down.\n"
  2001. "FROM Frq above/below which spectrum shifted (Range: 5 to nyquist/2).\n"
  2002. "GAIN Overall gain (Range: .1 to 1).\n"
  2003. "\n");
  2004. } else if(!strcmp(str,"invert")) {
  2005. fprintf(stdout,
  2006. "USAGE:\n"
  2007. "specnu invert inanalfile outanalfile top lopkratio hipkratio gain\n"
  2008. "\n"
  2009. "Inverts the spectral amplitudes over a specified range of the spectrum.\n"
  2010. "Using spectral peak to create spectral-amplitude-envelope used in inversion.\n"
  2011. "Referring to the inverted portion of the spectrum as \"invspec\" .....\n"
  2012. "\n"
  2013. "BOT Lowest frequency to include in invspec.\n"
  2014. "TOP Highest frequency to include in invspec.\n"
  2015. "PEAKTOP Highest frequency of area to search for spectral peak.\n"
  2016. " This must be within first half of invspec.\n"
  2017. "GAIN Overall gain (Range: .1 to 1).\n"
  2018. "\n");
  2019. } else if(!strcmp(str,"convolve")) {
  2020. fprintf(stdout,
  2021. "USAGE:\n"
  2022. "specnu convolve 1 inanalfile outanalfile gain [-ddepth]\n"
  2023. "specnu convolve 2 inanal1 inanal2 outanalfile gain [-ddepth]\n"
  2024. "\n"
  2025. "MODE 1 Convolve sound with itself.\n"
  2026. "MODE 2 Convolve two sounds : 2nd shorter or equal to 1st.\n"
  2027. "\n"
  2028. "GAIN Overall gain (Range: .1 to 1).\n"
  2029. "DEPTH Repeat process this number of times (Default once only).\n"
  2030. "\n");
  2031. } else if(!strcmp(str,"tosound")) {
  2032. fprintf(stdout,
  2033. "USAGE:\n"
  2034. "specnu tosound inanalfile outsndfile mintrans maxtrans\n"
  2035. "\n"
  2036. "Spectral envelope is treated as a waveform.\n"
  2037. "\n"
  2038. "Pitchline derived from local maximum amplitudes of the spectral windows.\n"
  2039. "These are placed in a range defined by the max and min limits given.\n"
  2040. "\n"
  2041. "MINTRANS Lower limit of 8va transposition (Range: 0 to 8).\n"
  2042. "MAXTRANS Upper limit of 8va transposition (Range: 1 to 8).\n"
  2043. "\n");
  2044. } else if(!strcmp(str,"fractal")) {
  2045. fprintf(stdout,
  2046. "USAGE:\n"
  2047. "specnu fractal 1-5 inanalfile outanalfile depth [-i]\n"
  2048. "\n"
  2049. "Create fractal version of spectrum.\n"
  2050. "NB Ouput sounds depend on number of analysis channels used in source.\n"
  2051. "\n"
  2052. "Mode 1: Abutt 2 copies, then shrink to orig size by time-contraction.\n"
  2053. "Mode 2: Abutt copy with reverse-copy, then shrink by time-contraction.\n"
  2054. "Mode 3: As mode 2, but cut into segments and process each segment in turn.\n"
  2055. "Mode 4: As mode 3, but shrink by averaging.\n"
  2056. "Mode 5: Swap two halves of segments.\n"
  2057. "Mode 6: reverse 2nd half of segments.\n"
  2058. "Mode 7: Interleave two halves of segments.\n"
  2059. "Mode 8: Reverse 2nd half of segments, then interleave.\n"
  2060. "Mode 9: Interleave, retaining original speed.\n"
  2061. "\n"
  2062. "DEPTH Degree of fractal segmentation.\n"
  2063. "-i Output all intermediate stages of fractalisation.\n"
  2064. "\n");
  2065. } else
  2066. fprintf(stdout,"Unknown option '%s'\n",str);
  2067. return(USAGE_ONLY);
  2068. }
  2069. int usage3(char *str1,char *str2)
  2070. {
  2071. fprintf(stderr,"Insufficient parameters on command line.\n");
  2072. return(USAGE_ONLY);
  2073. }
  2074. /*********************** INNER_LOOP ***************************/
  2075. int inner_loop
  2076. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  2077. {
  2078. int exit_status;
  2079. // int local_zero_set = FALSE;
  2080. int wc;
  2081. for(wc=0; wc<windows_in_buf; wc++) {
  2082. if(dz->total_windows==0) {
  2083. dz->flbufptr[0] += dz->wanted;
  2084. dz->total_windows++;
  2085. dz->time = (float)(dz->time + dz->frametime);
  2086. continue;
  2087. }
  2088. if((exit_status = read_values_from_all_existing_brktables((double)dz->time,dz))<0)
  2089. return(exit_status);
  2090. if((exit_status = spec_remove(dz))<0)
  2091. return(exit_status);
  2092. dz->flbufptr[0] += dz->wanted;
  2093. dz->total_windows++;
  2094. dz->time = (float)(dz->time + dz->frametime);
  2095. }
  2096. return FINISHED;
  2097. }
  2098. /*********************** SPEC_REMOVE ***************************/
  2099. int spec_remove(dataptr dz)
  2100. {
  2101. int vc, done, cnt;
  2102. double *lo, *hi, gain = 1.0 - dz->param[3], lofrq;
  2103. if(dz->zeroset) {
  2104. if(dz->mode == 0) {
  2105. for( vc = 0; vc < dz->wanted; vc += 2) {
  2106. if((dz->flbufptr[0][FREQ] >= dz->param[0]) && (dz->flbufptr[0][FREQ] <= dz->param[2]))
  2107. dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * gain);
  2108. }
  2109. } else {
  2110. for( vc = 0; vc < dz->wanted; vc += 2) {
  2111. if((dz->flbufptr[0][FREQ] <= dz->param[0]) || (dz->flbufptr[0][FREQ] >= dz->param[2]))
  2112. dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * gain);
  2113. }
  2114. }
  2115. } else {
  2116. cnt = 0;
  2117. done = 0;
  2118. lo = dz->parray[0];
  2119. hi = dz->parray[1];
  2120. if(dz->mode == 0) {
  2121. for( vc = 0; vc < dz->wanted; vc += 2) {
  2122. if((dz->flbufptr[0][FREQ] >= lo[cnt]) && (dz->flbufptr[0][FREQ] <= hi[cnt]))
  2123. dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * gain);
  2124. else {
  2125. while(dz->flbufptr[0][FREQ] >= hi[cnt]) {
  2126. cnt++;
  2127. if(cnt >= dz->itemcnt) {
  2128. done = 1;
  2129. break;
  2130. }
  2131. }
  2132. if(done)
  2133. break;
  2134. }
  2135. }
  2136. } else {
  2137. for( vc = 0; vc < dz->wanted; vc += 2) {
  2138. if(dz->flbufptr[0][FREQ] < lo[cnt])
  2139. dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * gain);
  2140. else {
  2141. if(cnt+1 >= dz->itemcnt)
  2142. lofrq = dz->nyquist;
  2143. else
  2144. lofrq = dz->nyquist = lo[cnt+1];
  2145. if(dz->flbufptr[0][FREQ] < lofrq && dz->flbufptr[0][FREQ] > hi[cnt]) {
  2146. dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * gain);
  2147. } else {
  2148. cnt++;
  2149. if(cnt >= dz->itemcnt) {
  2150. done = 1;
  2151. break;
  2152. }
  2153. }
  2154. }
  2155. if(done)
  2156. break;
  2157. }
  2158. }
  2159. }
  2160. return(FINISHED);
  2161. }
  2162. /**************************** DO_SPECLEAN ****************************/
  2163. int do_speclean(int subtract,dataptr dz)
  2164. {
  2165. int exit_status, cc, vc, k;
  2166. int n, samps_read, total_samps = 0;
  2167. float *fbuf, *obuf, *ibuf, *nbuf;
  2168. int *persist, *on, fadelim;
  2169. fadelim = dz->iparam[0] - 1;
  2170. fbuf = dz->bigfbuf;
  2171. obuf = dz->bigfbuf;
  2172. nbuf = dz->bigfbuf + (dz->buflen * dz->iparam[0]);
  2173. ibuf = nbuf - dz->buflen;
  2174. if((persist = (int *)malloc(dz->clength * sizeof(int)))==NULL) {
  2175. sprintf(errstr,"No memory for persistence counters.\n");
  2176. return(MEMORY_ERROR);
  2177. }
  2178. if((on = (int *)malloc(dz->clength * sizeof(int)))==NULL) {
  2179. sprintf(errstr,"No memory for persistence counters.\n");
  2180. return(MEMORY_ERROR);
  2181. }
  2182. memset((char *)persist,0,dz->clength * sizeof(int));
  2183. memset((char *)on,0,dz->clength * sizeof(int));
  2184. memset((char *)nbuf,0,dz->buflen * sizeof(float));
  2185. /* ESTABLISH NOISE CHANNEL-MAXIMA */
  2186. while((samps_read = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[1],0)) > 0) {
  2187. if(samps_read < 0) {
  2188. sprintf(errstr,"Failed to read data from noise file.\n");
  2189. return(SYSTEM_ERROR);
  2190. }
  2191. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc +=2) {
  2192. if(fbuf[AMPP] > nbuf[AMPP])
  2193. nbuf[AMPP] = fbuf[AMPP];
  2194. }
  2195. total_samps += samps_read;
  2196. }
  2197. if(total_samps <= 0) {
  2198. sprintf(errstr,"No data found in noise file.\n");
  2199. return(SYSTEM_ERROR);
  2200. }
  2201. /* MUTIPLY BY 'NOISEGAIN' FACTOR */
  2202. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc +=2)
  2203. nbuf[AMPP] = (float)(nbuf[AMPP] * dz->param[1]);
  2204. /* SKIP FIRST WINDOWS */
  2205. dz->samps_left = dz->insams[0];
  2206. if((samps_read = fgetfbufEx(obuf, dz->buflen,dz->ifd[0],0)) < 0) {
  2207. sprintf(errstr,"Failed to read data from signal file.\n");
  2208. return(SYSTEM_ERROR);
  2209. }
  2210. if(samps_read < dz->buflen) {
  2211. sprintf(errstr,"Problem reading data from signal file.\n");
  2212. return(PROGRAM_ERROR);
  2213. }
  2214. if((exit_status = write_samps(obuf,dz->wanted,dz))<0)
  2215. return(exit_status);
  2216. dz->samps_left -= dz->buflen;
  2217. /* READ IN FIRST GROUP OF SIGNAL WINDOWS */
  2218. dz->samps_left = dz->insams[0] - dz->wanted;
  2219. if((samps_read = fgetfbufEx(dz->bigfbuf, dz->buflen * dz->iparam[0],dz->ifd[0],0)) < 0) {
  2220. sprintf(errstr,"Failed to read data from signal file.\n");
  2221. return(SYSTEM_ERROR);
  2222. }
  2223. if(samps_read < dz->buflen * dz->iparam[0]) {
  2224. sprintf(errstr,"Problem reading data from signal file.\n");
  2225. return(PROGRAM_ERROR);
  2226. }
  2227. dz->samps_left -= dz->buflen * dz->iparam[0];
  2228. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc +=2) {
  2229. /* FOR EACH CHANNEL */
  2230. obuf = dz->bigfbuf;
  2231. fbuf = ibuf;
  2232. /* MOVING BACKWARDS THROUGH FIRST GROUP OF WINDOWS */
  2233. while(fbuf >= obuf) {
  2234. /* COUNT HOW MANY CONTIGUOUS WINDOWS EXCEED THE NOISE THRESHOLD */
  2235. if(fbuf[AMPP] > nbuf[AMPP])
  2236. persist[cc]++;
  2237. else
  2238. /* BUT IF ANY WINDOW IS BELOW NOISE THRESHOLD, BREAK */
  2239. break;
  2240. fbuf -= dz->buflen;
  2241. }
  2242. /* IF NOT ALL WINDOWS ARE ABOVE THE NOISE THRESHOLD, ZERO OUTPUT OF CHANNEL */
  2243. if(persist[cc] < dz->iparam[0])
  2244. obuf[AMPP] = 0.0f;
  2245. else {
  2246. on[cc] = 1;
  2247. if(subtract)
  2248. obuf[AMPP] = (float)max(0.0,obuf[AMPP] - nbuf[AMPP]);
  2249. }
  2250. }
  2251. /* WRITE FIRST OUT WINDOW */
  2252. if((exit_status = write_samps(obuf,dz->wanted,dz))<0)
  2253. return(exit_status);
  2254. obuf = dz->bigfbuf;
  2255. fbuf = obuf + dz->buflen;
  2256. /* MOVE ALL WINDOWS BACK ONE */
  2257. for(n = 1; n < dz->iparam[0]; n++) {
  2258. memcpy((char *)obuf,(char *)fbuf,dz->wanted * sizeof(float));
  2259. fbuf += dz->wanted;
  2260. obuf += dz->wanted;
  2261. }
  2262. obuf = dz->bigfbuf;
  2263. fbuf = obuf + dz->buflen;
  2264. while(dz->samps_left > 0) {
  2265. /* READ A NEW WINDOW TO END OF EXISTING GROUP */
  2266. if((samps_read = fgetfbufEx(ibuf,dz->buflen,dz->ifd[0],0)) < 0) {
  2267. sprintf(errstr,"Problem reading data from signal file.\n");
  2268. return(PROGRAM_ERROR);
  2269. }
  2270. dz->samps_left -= dz->wanted;
  2271. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc +=2) {
  2272. /* IF LEVEL IN ANY CHANNEL IN NEW WINDOW FALLS BELOW NOISE THRESHOLD */
  2273. if(subtract)
  2274. obuf[AMPP] = (float)max(0.0,obuf[AMPP] - nbuf[AMPP]);
  2275. if(ibuf[AMPP] < nbuf[AMPP]) {
  2276. /* IF CHANNEL IS ALREADY ON, KEEP IT, BUT DECREMENT ITS PERSISTENCE VALUE, and FADE OUTPUT LEVEL */
  2277. if(on[cc]) {
  2278. /* If it's persisted longer than min, reset persistence to min */
  2279. if(persist[cc] > dz->iparam[0])
  2280. persist[cc] = dz->iparam[0];
  2281. /* as persistence falls from min to zero, fade the output level */
  2282. if(--persist[cc] <= 0) {
  2283. on[cc] = 0;
  2284. obuf[AMPP] = 0.0f;
  2285. } else
  2286. obuf[AMPP] = (float)(obuf[AMPP] * ((double)persist[cc]/(double)dz->iparam[0]));
  2287. } else
  2288. /* ELSE, SET OUTPUT TO ZERO */
  2289. obuf[AMPP] = 0.0f;
  2290. } else {
  2291. /* IF CHANNEL LEVEL IS ABOVE NOISE THRESHOLD, COUNT ITS PERSISTANCE */
  2292. persist[cc]++;
  2293. /* IF ON ALREADY, RETAIN SIGNAL */
  2294. if(on[cc])
  2295. ;
  2296. /* ELSE IF PERSISTENCE IS INSUFFICIENT, ZERO OUTPUT */
  2297. else if((k = persist[cc] - dz->iparam[0]) < 0)
  2298. obuf[AMPP] = 0.0f;
  2299. else {
  2300. /* ELSE IF PERSISTANCE IS BELOW FADELIM, FADE IN THAT OUTPUT */
  2301. if(persist[cc] < fadelim)
  2302. obuf[AMPP] = (float)(obuf[AMPP] * ((double)k/(double)dz->iparam[0]));
  2303. /* ELSE RETAIN FULL LEVEL AND MARK CHANNEL AS (FULLY) ON */
  2304. else
  2305. on[cc] = 1;
  2306. }
  2307. }
  2308. }
  2309. /* WRITE THE OUTPUT */
  2310. if((exit_status = write_samps(obuf,dz->wanted,dz))<0)
  2311. return(exit_status);
  2312. /* MOVE ALL WINDOWS BACK ONE */
  2313. if(dz->samps_left) {
  2314. for(n = 1; n < dz->iparam[0]; n++) {
  2315. memcpy((char *)obuf,(char *)fbuf,dz->wanted * sizeof(float));
  2316. fbuf += dz->wanted;
  2317. obuf += dz->wanted;
  2318. }
  2319. }
  2320. obuf = dz->bigfbuf;
  2321. fbuf = obuf + dz->buflen;
  2322. }
  2323. /* DEAL WITH REMAINDER OF FINAL BLOCK OF WINDOWS */
  2324. obuf += dz->buflen;
  2325. /* ADVANCING THROUGH THE WINDOWS */
  2326. while(obuf < nbuf) {
  2327. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc +=2) {
  2328. if(!on[cc])
  2329. obuf[AMPP] = 0.0f;
  2330. else if(obuf[AMPP] < nbuf[AMPP]) {
  2331. obuf[AMPP] = 0.0f;
  2332. on[cc] = 0;
  2333. } else if(subtract)
  2334. obuf[AMPP] = (float)max(0.0,obuf[AMPP] - nbuf[AMPP]);
  2335. }
  2336. if((exit_status = write_samps(obuf,dz->wanted,dz))<0)
  2337. return(exit_status);
  2338. obuf += dz->buflen;
  2339. }
  2340. return FINISHED;
  2341. }
  2342. /************************ GET_THE_MODE_NO *********************/
  2343. int get_the_mode_no(char *str, dataptr dz)
  2344. {
  2345. if(sscanf(str,"%d",&dz->mode)!=1) {
  2346. sprintf(errstr,"Cannot read mode of program.\n");
  2347. return(USAGE_ONLY);
  2348. }
  2349. if(dz->mode <= 0 || dz->mode > dz->maxmode) {
  2350. sprintf(errstr,"Program mode value [%d] is out of range [1 - %d].\n",dz->mode,dz->maxmode);
  2351. return(USAGE_ONLY);
  2352. }
  2353. dz->mode--; /* CHANGE TO INTERNAL REPRESENTATION OF MODE NO */
  2354. return(FINISHED);
  2355. }
  2356. /************************ HANDLE_PITCHDATA *********************/
  2357. int handle_pitchdata(int *cmdlinecnt,char ***cmdline,dataptr dz)
  2358. {
  2359. int istime, valcnt;
  2360. aplptr ap = dz->application;
  2361. int n;
  2362. char temp[200], *q, *filename = (*cmdline)[0];
  2363. double *p, lasttime = 0.0, maxfrq = -100.0, thisharmfrq;
  2364. if(!sloom) {
  2365. if(*cmdlinecnt <= 0) {
  2366. sprintf(errstr,"Insufficient parameters on command line.\n");
  2367. return(USAGE_ONLY);
  2368. }
  2369. }
  2370. ap->data_in_file_only = TRUE;
  2371. ap->special_range = TRUE;
  2372. ap->min_special = SPEC_MINFRQ;
  2373. ap->max_special = (dz->nyquist * 2.0)/3.0;
  2374. if((dz->fp = fopen(filename,"r"))==NULL) {
  2375. sprintf(errstr,"Cannot open datafile %s\n",filename);
  2376. return(DATA_ERROR);
  2377. }
  2378. n = 0;
  2379. while(fgets(temp,200,dz->fp)!=NULL) {
  2380. q = temp;
  2381. if(is_an_empty_line_or_a_comment(q))
  2382. continue;
  2383. n++;
  2384. }
  2385. if(n==0) {
  2386. sprintf(errstr,"No data in file %s\n",filename);
  2387. return(DATA_ERROR);
  2388. }
  2389. dz->brksize[1] = n;
  2390. if ((dz->brk[1] = (double *)malloc(dz->brksize[1] * 2 * sizeof(double)))==NULL) {
  2391. sprintf(errstr,"Insufficient memory to store pitch data\n");
  2392. return(MEMORY_ERROR);
  2393. }
  2394. p = dz->brk[1];
  2395. if(fseek(dz->fp,0,0)<0) {
  2396. sprintf(errstr,"fseek() failed in handle_pitchdata()\n");
  2397. return(SYSTEM_ERROR);
  2398. }
  2399. n = 0;
  2400. while(fgets(temp,200,dz->fp)!=NULL) {
  2401. q = temp;
  2402. if(is_an_empty_line_or_a_comment(temp))
  2403. continue;
  2404. if(n >= dz->brksize[1]) {
  2405. sprintf(errstr,"Accounting problem reading pitchdata\n");
  2406. return(PROGRAM_ERROR);
  2407. }
  2408. istime = 1;
  2409. valcnt = 0;
  2410. while(get_float_from_within_string(&q,p)) {
  2411. if(valcnt>=2) {
  2412. sprintf(errstr,"Too many values on line %d: file %s\n",n+1,filename);
  2413. return(DATA_ERROR);
  2414. }
  2415. if(istime) {
  2416. if(n == 0) {
  2417. lasttime = *p;
  2418. } else {
  2419. if(*p <= lasttime) {
  2420. sprintf(errstr,"Times fail to advance: line %d: file %s\n",n+1,filename);
  2421. return(DATA_ERROR);
  2422. }
  2423. }
  2424. } else {
  2425. if(*p <= ap->min_special || *p >= ap->max_special) {
  2426. sprintf(errstr,"Pitch out of range (%lf - %lf) : line %d: file %s\n",ap->min_special,ap->max_special,n+1,filename);
  2427. return(DATA_ERROR);
  2428. }
  2429. maxfrq = max(maxfrq,*p);
  2430. }
  2431. istime = !istime;
  2432. valcnt++;
  2433. p++;
  2434. }
  2435. if(!istime) {
  2436. sprintf(errstr,"Time-pitch brkpnt data not correctly paired: line %d: file %s\n",n+1,filename);
  2437. return(DATA_ERROR);
  2438. }
  2439. n++;
  2440. }
  2441. dz->brksize[1] = n;
  2442. if(fclose(dz->fp)<0) {
  2443. fprintf(stdout,"WARNING: Failed to close input textfile %s.\n",filename);
  2444. fflush(stdout);
  2445. }
  2446. dz->harmcnt = 0;
  2447. thisharmfrq = maxfrq;
  2448. while(thisharmfrq < dz->nyquist) {
  2449. dz->harmcnt++;
  2450. thisharmfrq += maxfrq;
  2451. }
  2452. if(dz->harmcnt == 0) {
  2453. sprintf(errstr,"No valid count of harmonics found in file.\n");
  2454. return DATA_ERROR;
  2455. }
  2456. (*cmdline)++;
  2457. (*cmdlinecnt)--;
  2458. return(FINISHED);
  2459. }
  2460. /**************************** DO_SPECSLICE ****************************/
  2461. int do_specslice(dataptr dz)
  2462. {
  2463. int n, exit_status;
  2464. float *ibuf = dz->bigfbuf, *obuf = dz->bigfbuf;
  2465. double bigstep, thistime, bandbot, bandtop, frqmult;
  2466. int ibigstep, ibandbot, ibandtop, cc, vc;
  2467. int samps_read;
  2468. n = 0;
  2469. if(dz->mode == 4) {
  2470. exit_status = specpivot(dz);
  2471. return(exit_status);
  2472. }
  2473. // JULY 2020
  2474. dz->itemcnt = -1;
  2475. if(dz->mode == 3)
  2476. dz->param[0] = dz->harmcnt;
  2477. // JULY 2020 ABOVE
  2478. while(n < dz->param[0]) {
  2479. dz->total_samps_written = 0;
  2480. if(sndseekEx(dz->ifd[0],0,0)<0) {
  2481. sprintf(errstr,"Seek failed in input analysis file.\n");
  2482. return(SYSTEM_ERROR);
  2483. }
  2484. if((exit_status = create_next_outfile(dz)) < 0) {
  2485. return(exit_status);
  2486. }
  2487. thistime = 0.0;
  2488. while((samps_read = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[0],0)) > 0) {
  2489. if(samps_read < 0) {
  2490. sprintf(errstr,"Failed to read data from input file.\n");
  2491. return(SYSTEM_ERROR);
  2492. }
  2493. if(dz->mode < 3) {
  2494. if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
  2495. return(exit_status);
  2496. }
  2497. switch(dz->mode) {
  2498. case(0):
  2499. ibigstep = dz->iparam[0] * dz->iparam[1];
  2500. ibandbot = dz->iparam[1] * n;
  2501. ibandtop = ibandbot + dz->iparam[1];
  2502. if(ibandbot >= dz->clength) {
  2503. sprintf(errstr,"Failure in internal channel accounting.\n");
  2504. return(PROGRAM_ERROR);
  2505. }
  2506. cc = 0;
  2507. while(cc < dz->clength) {
  2508. vc = cc * 2;
  2509. while(cc < ibandbot) {
  2510. ibuf[AMPP] = 0.0f; /* SETS AMPLITUDE OUTSIDE SELECTED BANDS TO ZERO */
  2511. cc++;
  2512. vc += 2;
  2513. }
  2514. while(cc < ibandtop) {
  2515. cc++;
  2516. vc += 2;
  2517. }
  2518. if((ibandbot += ibigstep) >= dz->clength)
  2519. ibandbot = dz->clength;
  2520. if((ibandtop = ibandbot + dz->iparam[1]) >= dz->clength)
  2521. ibandtop = dz->clength;
  2522. }
  2523. break;
  2524. case(1):
  2525. bigstep = dz->param[1] * (double)dz->iparam[0];
  2526. bandbot = dz->param[1] * (double)n;
  2527. if(bandbot >= dz->nyquist) {
  2528. sprintf(errstr,"Failure in internal channel accounting.\n");
  2529. return(PROGRAM_ERROR);
  2530. }
  2531. if((bandtop = bandbot + dz->param[1]) >= dz->nyquist)
  2532. bandtop = dz->nyquist;
  2533. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc +=2) {
  2534. if(ibuf[FREQ] < bandbot)
  2535. ibuf[AMPP] = 0.0f;
  2536. else if(ibuf[FREQ] >= bandtop) {
  2537. ibuf[AMPP] = 0.0f;
  2538. // if((bandbot = bandbot + bigstep) >= dz->nyquist)
  2539. // bandtop = dz->nyquist;
  2540. // if((bandtop = bandbot + dz->param[1]) >= dz->nyquist)
  2541. // bandtop = dz->nyquist;
  2542. }
  2543. }
  2544. break;
  2545. case(2):
  2546. frqmult = 1.0 + pow(2.0,dz->param[1]/SEMITONES_PER_OCTAVE);
  2547. bandbot = dz->chwidth * pow(frqmult,(double)n);
  2548. bigstep = pow(frqmult,(double)dz->iparam[0]);
  2549. if((bandtop = bandbot * frqmult) >= dz->nyquist)
  2550. bandtop = dz->nyquist;
  2551. if(n == 0)
  2552. bandbot = 0.0;
  2553. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc +=2) {
  2554. if(ibuf[FREQ] < bandbot)
  2555. ibuf[AMPP] = 0.0f;
  2556. else if(ibuf[FREQ] >= bandtop) {
  2557. ibuf[AMPP] = 0.0f;
  2558. // if((bandbot *= bigstep) >= dz->nyquist)
  2559. // bandbot = dz->nyquist;
  2560. // if((bandtop = bandbot * frqmult) >= dz->nyquist)
  2561. // bandtop = dz->nyquist;
  2562. }
  2563. }
  2564. break;
  2565. case(3):
  2566. if((exit_status = read_value_from_brktable(thistime,1,dz))<0)
  2567. return(exit_status);
  2568. bandbot = (dz->param[1] * (double)n) + (dz->param[1]/2.0);
  2569. if(bandbot >= dz->nyquist) {
  2570. sprintf(errstr,"Failure in internal channel accounting.\n");
  2571. return(PROGRAM_ERROR);
  2572. }
  2573. bandtop = (dz->param[1] * (double)(n+1)) + (dz->param[1]/2.0);
  2574. if(n == 0)
  2575. bandbot = 0.0;
  2576. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc +=2) {
  2577. if(ibuf[FREQ] < bandbot)
  2578. ibuf[AMPP] = 0.0f;
  2579. else if(ibuf[FREQ] >= bandtop)
  2580. ibuf[AMPP] = 0.0f;
  2581. }
  2582. break;
  2583. }
  2584. thistime += dz->frametime;
  2585. if((exit_status = write_samps(obuf,dz->wanted,dz))<0)
  2586. return(exit_status);
  2587. }
  2588. if((exit_status = headwrite(dz->ofd,dz))<0)
  2589. return(exit_status);
  2590. if((exit_status = reset_peak_finder(dz))<0)
  2591. return(exit_status);
  2592. if (n < dz->param[0] - 1) {
  2593. if(sndcloseEx(dz->ofd) < 0) {
  2594. fprintf(stdout,"WARNING: Can't close output soundfile %s\n",dz->outfilename);
  2595. fflush(stdout);
  2596. }
  2597. dz->ofd = -1;
  2598. }
  2599. n++;
  2600. }
  2601. return FINISHED;
  2602. }
  2603. /**************************** SETUP_SPECSLICE_PARAMETER_STORAGE ****************************/
  2604. int setup_specslice_parameter_storage(dataptr dz) {
  2605. if((dz->brk = (double **)realloc(dz->brk,2 * sizeof(double *)))==NULL) {
  2606. sprintf(errstr,"setup_specslice_parameter_storage(): 1\n");
  2607. return(MEMORY_ERROR);
  2608. }
  2609. if((dz->brkptr = (double **)realloc(dz->brkptr,2 * sizeof(double *)))==NULL) {
  2610. sprintf(errstr,"setup_specslice_parameter_storage(): 6\n");
  2611. return(MEMORY_ERROR);
  2612. }
  2613. if((dz->brksize = (int *)realloc(dz->brksize,2 * sizeof(int)))==NULL) {
  2614. sprintf(errstr,"setup_specslice_parameter_storage(): 2\n");
  2615. return(MEMORY_ERROR);
  2616. }
  2617. if((dz->firstval = (double *)realloc(dz->firstval,2 * sizeof(double)))==NULL) {
  2618. sprintf(errstr,"setup_specslice_parameter_storage(): 3\n");
  2619. return(MEMORY_ERROR);
  2620. }
  2621. if((dz->lastind = (double *)realloc(dz->lastind,2 * sizeof(double)))==NULL) {
  2622. sprintf(errstr,"setup_specslice_parameter_storage(): 4\n");
  2623. return(MEMORY_ERROR);
  2624. }
  2625. if((dz->lastval = (double *)realloc(dz->lastval,2 * sizeof(double)))==NULL) {
  2626. sprintf(errstr,"setup_specslice_parameter_storage(): 5\n");
  2627. return(MEMORY_ERROR);
  2628. }
  2629. if((dz->brkinit = (int *)realloc(dz->brkinit,2 * sizeof(int)))==NULL) {
  2630. sprintf(errstr,"setup_specslice_parameter_storage(): 7\n");
  2631. return(MEMORY_ERROR);
  2632. }
  2633. dz->brk[1] = NULL;
  2634. dz->brkptr[1] = NULL;
  2635. dz->brkinit[1] = 0;
  2636. dz->brksize[1] = 0;
  2637. if((dz->param = (double *)realloc(dz->param,2 * sizeof(double)))==NULL) {
  2638. sprintf(errstr,"setup_specslice_parameter_storage(): 1\n");
  2639. return(MEMORY_ERROR);
  2640. }
  2641. if((dz->iparam = (int *)realloc(dz->iparam, 2 * sizeof(int) ))==NULL) {
  2642. sprintf(errstr,"setup_specslice_parameter_storage(): 2\n");
  2643. return(MEMORY_ERROR);
  2644. }
  2645. if((dz->is_int = (char *)realloc(dz->is_int,2 * sizeof(char)))==NULL) {
  2646. sprintf(errstr,"setup_specslice_parameter_storage(): 3\n");
  2647. return(MEMORY_ERROR);
  2648. }
  2649. if((dz->no_brk = (char *)realloc(dz->no_brk,2 * sizeof(char)))==NULL) {
  2650. sprintf(errstr,"setup_specslice_parameter_storage(): 5\n");
  2651. return(MEMORY_ERROR);
  2652. }
  2653. if((dz->is_active = (char *)realloc(dz->is_active,2 * sizeof(char)))==NULL) {
  2654. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  2655. return(MEMORY_ERROR);
  2656. }
  2657. dz->is_int[1] = 0;
  2658. dz->is_active[1] = 1;
  2659. dz->no_brk[1] = (char)0;
  2660. return FINISHED;
  2661. }
  2662. /************************************ SPECPIVOT **************************************/
  2663. int specpivot(dataptr dz)
  2664. {
  2665. int exit_status, nullspec = 0, pivot = 0, vc1 = 0, vc2 = 0;
  2666. float temp;
  2667. int samps_read;
  2668. double thistime = 0.0;
  2669. if(dz->brksize[0] == 0) {
  2670. pivot = (int)round(dz->param[0]/dz->chwidth);
  2671. pivot *= 2;
  2672. vc1 = pivot - 2;
  2673. vc2 = pivot + 2;
  2674. if(vc1 < 0 || vc2 >= dz->wanted) {
  2675. sprintf(errstr,"Pivot frequency will generate a null spectrum\n");
  2676. return(DATA_ERROR);
  2677. }
  2678. }
  2679. while((samps_read = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[0],0)) > 0) {
  2680. if(dz->brksize[0]) {
  2681. if((exit_status = read_value_from_brktable(thistime,0,dz))<0)
  2682. return(exit_status);
  2683. pivot = (int)round(dz->param[0]/dz->chwidth);
  2684. if(vc1 < 0 || vc2 >= dz->wanted)
  2685. nullspec = 1;
  2686. }
  2687. vc1 = pivot - 2;
  2688. vc2 = pivot + 2;
  2689. for(;;) {
  2690. if(vc1 < 0) {
  2691. while(vc2 < dz->wanted) {
  2692. dz->bigfbuf[vc2] = 0.0f;
  2693. vc2 += 2;
  2694. }
  2695. break;
  2696. } else if(vc2 >= dz->wanted) {
  2697. while(vc1 >= 0) {
  2698. dz->bigfbuf[vc1] = 0.0f;
  2699. vc1 -= 2;
  2700. }
  2701. break;
  2702. } else {
  2703. temp = dz->bigfbuf[vc1];
  2704. dz->bigfbuf[vc1] = dz->bigfbuf[vc2];
  2705. dz->bigfbuf[vc2] = temp;
  2706. vc1 -= 2;
  2707. vc2 += 2;
  2708. }
  2709. }
  2710. if((exit_status = write_samps(dz->bigfbuf,samps_read,dz))<0)
  2711. return(exit_status);
  2712. thistime += dz->frametime;
  2713. }
  2714. if(nullspec) {
  2715. fprintf(stdout,"WARNING: some spectral windows ZEROed as pivot frq was too high or too low\n");
  2716. fflush(stdout);
  2717. }
  2718. if(samps_read < 0) {
  2719. sprintf(errstr,"Failed to read data from input file.\n");
  2720. return(SYSTEM_ERROR);
  2721. }
  2722. return FINISHED;
  2723. }
  2724. /************************************ SPECRAND **************************************/
  2725. int specrand(dataptr dz)
  2726. {
  2727. int n, m, exit_status, done = 0, outwindowcnt = 0;
  2728. float *obuf = dz->bigfbuf;
  2729. int samps_read;
  2730. unsigned int thissample;
  2731. double thistime = 0.0;
  2732. int windowframestart, windowrangesize, windowgroupsize, scramblesetsize, thisgrpstart, thiswindow;
  2733. int *perm = dz->iparray[1], *rwindow = dz->iparray[0];
  2734. fprintf(stdout,"INFO: Calculating output window sequence.\n");
  2735. fflush(stdout);
  2736. windowframestart = 0;
  2737. while(windowframestart < dz->wlength) {
  2738. if(dz->brksize[0]) {
  2739. if((exit_status = read_value_from_brktable(thistime,0,dz))<0)
  2740. return(exit_status);
  2741. dz->iparam[0] = (int)round(dz->param[0]/dz->frametime);
  2742. if(dz->iparam[0] < 2)
  2743. dz->iparam[0] = 2; // Get size of timeframe (in windows) to randomise
  2744. }
  2745. windowrangesize = dz->iparam[0];
  2746. windowgroupsize = dz->iparam[1];
  2747. scramblesetsize = windowrangesize/windowgroupsize; // Number of window-groups to permute
  2748. rndintperm(perm,scramblesetsize); // Randomise order
  2749. for(n = 0; n < scramblesetsize; n++) {
  2750. thisgrpstart = perm[n] * windowgroupsize; // Find start of next (permd) group-of-windows, from zero baseline
  2751. thiswindow = thisgrpstart + windowframestart; // Find true window this refers to
  2752. for(m=0;m<windowgroupsize;m++) { // For all windows in group
  2753. if(thiswindow >= dz->wlength)
  2754. break;
  2755. if(outwindowcnt >= dz->wlength) {
  2756. done = 1;
  2757. break;
  2758. }
  2759. rwindow[outwindowcnt++] = thiswindow++; // Assign window as next in output sequence of windows
  2760. }
  2761. if(done)
  2762. break;
  2763. }
  2764. windowframestart += windowrangesize;
  2765. thistime += windowrangesize * dz->frametime;
  2766. }
  2767. fprintf(stdout,"INFO: Writing output windows.\n");
  2768. fflush(stdout);
  2769. for(n = 0; n < dz->wlength;n++) {
  2770. thiswindow = rwindow[n];
  2771. thissample = thiswindow * dz->wanted;
  2772. if((sndseekEx(dz->ifd[0],thissample,0)<0)){
  2773. sprintf(errstr,"sndseek() failed at window %d at time %lf : thissample = %d len = %d windows = %d\n",thiswindow,thiswindow * dz->frametime,thissample,dz->insams[0],dz->wlength);
  2774. return SYSTEM_ERROR;
  2775. }
  2776. if((samps_read = fgetfbufEx(obuf, dz->buflen,dz->ifd[0],0)) < 0) {
  2777. sprintf(errstr,"Failed to read data from input file at time %lf.\n",thiswindow * dz->frametime);
  2778. return(SYSTEM_ERROR);
  2779. }
  2780. if((exit_status = write_samps(obuf,dz->wanted,dz))<0)
  2781. return(exit_status);
  2782. }
  2783. return FINISHED;
  2784. }
  2785. /*********************** RNDINTPERM ************************/
  2786. void rndintperm(int *perm,int cnt)
  2787. {
  2788. int n,t,k;
  2789. memset((char *)perm,0,cnt * sizeof(int));
  2790. for(n=0;n<cnt;n++) {
  2791. t = (int)(drand48() * (double)(n+1)); /* TRUNCATE */
  2792. if(t==n) {
  2793. for(k=n;k>0;k--)
  2794. perm[k] = perm[k-1];
  2795. perm[0] = n;
  2796. } else {
  2797. for(k=n;k>t;k--)
  2798. perm[k] = perm[k-1];
  2799. perm[t] = n;
  2800. }
  2801. }
  2802. }
  2803. /************************************ SPECSQZ **************************************/
  2804. int specsqz(dataptr dz)
  2805. {
  2806. int exit_status, cc, vc;
  2807. double centrefrq, squeeze, thisamp, thisfrq;
  2808. int thischan;
  2809. int samps_read;
  2810. float *ibuf = dz->bigfbuf, *obuf = dz->flbufptr[2];
  2811. double thistime = 0.0;
  2812. while((samps_read = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[0],0)) > 0) {
  2813. if(samps_read < 0) {
  2814. sprintf(errstr,"Failed to read data from input file.\n");
  2815. return(SYSTEM_ERROR);
  2816. }
  2817. memset((char *)obuf,0,dz->wanted * sizeof(float));
  2818. if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
  2819. return exit_status;
  2820. centrefrq = dz->param[0];
  2821. squeeze = dz->param[1];
  2822. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc +=2) {
  2823. thisamp = ibuf[AMPP];
  2824. thisfrq = ibuf[FREQ] - centrefrq;
  2825. thisfrq *= squeeze;
  2826. thisfrq += centrefrq;
  2827. thischan = (int)round(thisfrq/dz->chwidth);
  2828. if(thisamp > obuf[thischan * 2])
  2829. obuf[thischan * 2] = (float)thisamp;
  2830. }
  2831. if((exit_status = write_samps(obuf,samps_read,dz))<0)
  2832. return(exit_status);
  2833. thistime += dz->frametime;
  2834. }
  2835. return FINISHED;
  2836. }
  2837. /**************************** ALLOCATE_SPECSQZ_BUFFER ******************************/
  2838. int allocate_specsqz_buffer(dataptr dz)
  2839. {
  2840. // int exit_status;
  2841. unsigned int buffersize;
  2842. if(dz->bptrcnt < 4) {
  2843. sprintf(errstr,"Insufficient bufptrs established in allocate_double_buffer()\n");
  2844. return(PROGRAM_ERROR);
  2845. }
  2846. //TW REVISED: buffers don't need to be multiples of secsize
  2847. buffersize = dz->wanted;
  2848. dz->buflen = buffersize;
  2849. if((dz->bigfbuf = (float*)malloc(dz->buflen*2 * sizeof(float)))==NULL) {
  2850. sprintf(errstr,"INSUFFICIENT MEMORY for sound buffers.\n");
  2851. return(MEMORY_ERROR);
  2852. }
  2853. dz->big_fsize = dz->buflen;
  2854. dz->flbufptr[2] = dz->bigfbuf + dz->big_fsize;
  2855. dz->flbufptr[3] = dz->flbufptr[2] + dz->big_fsize;
  2856. return(FINISHED);
  2857. }
  2858. /********************************** SPECSYNC **********************************/
  2859. int specsync(dataptr dz)
  2860. {
  2861. int exit_status = CONTINUE, owcnt = 0; // owcnt = window-position in output buffer
  2862. int n, thatwindow = 0, pad, remain;
  2863. double *syncto = dz->parray[0], *syncfrom = dz->parray[1];
  2864. double abswinptr = 0.0, stretch, incr, startsyncto; // abswinptr points to current time in spectrum being stretched.
  2865. int winptr = 0; // winptr points to current window in spectrum being stretched.
  2866. startsyncto = syncto[0];
  2867. if((exit_status = generate_zero_window(&owcnt,0,dz))<0) // output always starts with a zero-window
  2868. return exit_status;
  2869. // Where sync-to times starts at zero but syncfrom time is > zero:
  2870. // move pointer in INPUT FILE to relevant (post-zero) window.
  2871. if(syncto[0] == 0.0 && syncfrom[0] > 0.0) {
  2872. winptr = (int) round(syncfrom[0]);
  2873. abswinptr = (double)winptr;
  2874. // Where sync-to times start AFTER zero, but sync-from times start at zero:
  2875. // pad output with zero-windows
  2876. } else if(syncto[0] > 0.0 && syncfrom[0] == 0.0) {
  2877. pad = (int) round(syncto[0]);
  2878. while(pad > 1) { // If this is more than a window length after start of sync-to file, pad output with zero-windows.
  2879. if((exit_status = generate_zero_window(&owcnt,0,dz))<0)
  2880. return exit_status;
  2881. pad--;
  2882. }
  2883. // Where Neither first sync-point is at zero, put in extra points at time zero
  2884. // If you want files NOT to start in sync, pre-pad with silence
  2885. } else if(syncto[0] > 0.0 && syncfrom[0] > 0.0) {
  2886. for(n = dz->itemcnt;n > 0; n--) {
  2887. syncto[n] = syncto[n-1];
  2888. syncfrom[n] = syncfrom[n-1];
  2889. }
  2890. syncto[0] = syncfrom[0] = 1; // Start from window 1
  2891. startsyncto = syncto[0];
  2892. dz->itemcnt++;
  2893. }
  2894. for(n=1;n<dz->itemcnt;n++) { // Stretch outfile by required timestep divided by actual timestep.
  2895. stretch = (syncto[n] - startsyncto)/(syncfrom[n] - syncfrom[n-1]);
  2896. incr = 1.0/stretch; // To make it longer (stretch > 1), incr in outfile is <1 ... and vice versa.
  2897. while(abswinptr < syncfrom[n]) { // Stretch file until we reach required time
  2898. if((exit_status = do_timestretching(&thatwindow,&owcnt,abswinptr,dz))<0)
  2899. return exit_status;
  2900. if(exit_status == FINISHED)
  2901. break;
  2902. abswinptr += incr;
  2903. if(abswinptr >= dz->wlength-1) { // If we reach final window of input, set FINISHED and quit
  2904. exit_status = FINISHED;
  2905. break;
  2906. }
  2907. }
  2908. if(exit_status == FINISHED)
  2909. break; // SELF-CORRECTION!!!!
  2910. startsyncto = (double)(dz->total_windows_written + owcnt); // Revise start-time of syncto seg to be same as time actually reached in output
  2911. } // So length ratio for stretching calcd from true position (not where we're theortically at)
  2912. if(exit_status != FINISHED) {
  2913. incr = 1.0; // If any of infile remains, read it out
  2914. while(abswinptr < dz->wlength-1) {
  2915. if((exit_status = do_timestretching(&thatwindow,&owcnt,abswinptr,dz))<0)
  2916. return exit_status;
  2917. if(exit_status == FINISHED)
  2918. break;
  2919. abswinptr += incr;
  2920. }
  2921. }
  2922. if((exit_status = copy_final_window(&owcnt,dz))<0) // Ensure final window is copied
  2923. return exit_status;;
  2924. if((exit_status = generate_zero_window(&owcnt,1,dz))<0) // Add a zero window at end, to avoid clip (will this work??)
  2925. return exit_status;
  2926. if((remain = dz->flbufptr[OHERE] - dz->flbufptr[OBUF]) > 0) { // Write any remaining samples
  2927. if((exit_status = write_samps(dz->flbufptr[OBUF],remain,dz))<0)
  2928. return(exit_status);
  2929. }
  2930. return FINISHED;
  2931. }
  2932. /*************************** DO_TIMESTRETCHING ********************************
  2933. *
  2934. * Read/interpolate source analysis windows.
  2935. *
  2936. * (1) The initial window to intepolate FROM is found by truncating the non-integer window count
  2937. * e.g. position 3.2 translates to window 3.
  2938. * (2) Is this is a move on from the current window position? How far?
  2939. * (3) If we need to move on, call advance-windows and set up a new PAIR of
  2940. * input windows.
  2941. * (4) Get Interpolation time-fraction.
  2942. * (5) Get output values by interpolation between input values.
  2943. * (6) Advance window-count in output buffer.
  2944. * (7) If outbuf full, write a complete out-windowbuf to output file, and reset outputbuf window-count to zero.
  2945. */
  2946. int do_timestretching(int *thatwindow,int *owcnt,double abswinptr,dataptr dz)
  2947. {
  2948. int exit_status;
  2949. double amp0, amp1, frq0, frq1;
  2950. int vc;
  2951. int thiswindow, step;
  2952. double frac;
  2953. thiswindow = (int) abswinptr; /* TRUNCATE */ /* 1 */
  2954. step = thiswindow - *thatwindow; /* 2 */
  2955. if(step) { /* 3 */
  2956. if((exit_status = advance_along_input_windows(step,dz))<0)
  2957. return(exit_status);
  2958. if(exit_status == FINISHED) // No more input to read
  2959. return(FINISHED);
  2960. }
  2961. frac = abswinptr - (double)thiswindow; /* 4 */
  2962. for(vc = 0; vc < dz->wanted; vc += 2) {
  2963. amp0 = dz->flbufptr[IHERE][AMPP]; /* 5 */
  2964. frq0 = dz->flbufptr[IHERE][FREQ];
  2965. amp1 = dz->flbufptr[INEXT][AMPP];
  2966. frq1 = dz->flbufptr[INEXT][FREQ];
  2967. dz->flbufptr[OHERE][AMPP] = (float)(amp0 + ((amp1 - amp0) * frac));
  2968. dz->flbufptr[OHERE][FREQ] = (float)(frq0 + ((frq1 - frq0) * frac));
  2969. }
  2970. (*owcnt)++; /* 6 */
  2971. if((dz->flbufptr[OHERE] += dz->wanted) >= dz->flbufptr[OEND]) {
  2972. if((exit_status = write_exact_samps(dz->flbufptr[OBUF],dz->buflen,dz))<0)
  2973. return(exit_status); /* 7 */
  2974. dz->flbufptr[OHERE] = dz->flbufptr[OBUF];
  2975. dz->total_windows_written += SYNCBUFSCNT;
  2976. *owcnt = 0;
  2977. }
  2978. *thatwindow = thiswindow;
  2979. return(CONTINUE);
  2980. }
  2981. /*************************** COPY_FINAL_WINDOW ****************************/
  2982. int copy_final_window(int *owcnt,dataptr dz)
  2983. {
  2984. int exit_status;
  2985. int vc;
  2986. for(vc = 0; vc < dz->wanted; vc += 2) {
  2987. dz->flbufptr[OHERE][AMPP] = dz->flbufptr[IHERE][AMPP];
  2988. dz->flbufptr[OHERE][FREQ] = dz->flbufptr[IHERE][FREQ];
  2989. }
  2990. (*owcnt)++;
  2991. memcpy((char *)dz->flbufptr[OEND],(char *)dz->flbufptr[OHERE],dz->wanted * sizeof(float)); // remember last window written, to set final zero-window vals
  2992. if((dz->flbufptr[OHERE] += dz->wanted) >= dz->flbufptr[2]) {
  2993. if((exit_status = write_exact_samps(dz->flbufptr[OBUF],dz->buflen,dz))<0)
  2994. return(exit_status); /* 6 */
  2995. dz->flbufptr[OHERE] = dz->flbufptr[OBUF];
  2996. dz->total_windows_written += SYNCBUFSCNT;
  2997. *owcnt = 0;
  2998. }
  2999. return(FINISHED);
  3000. }
  3001. /*************************** GENERATE_ZERO_WINDOW ****************************/
  3002. int generate_zero_window(int *owcnt,int atend,dataptr dz)
  3003. {
  3004. int exit_status;
  3005. int vc;
  3006. if(atend) {
  3007. for(vc = 0; vc < dz->wanted; vc += 2) {
  3008. dz->flbufptr[OHERE][AMPP] = (float)0.0;
  3009. dz->flbufptr[OHERE][FREQ] = dz->flbufptr[OEND][FREQ]; // Retain frqs of last window written
  3010. }
  3011. } else {
  3012. for(vc = 0; vc < dz->wanted; vc += 2) {
  3013. dz->flbufptr[OHERE][AMPP] = (float)0.0;
  3014. dz->flbufptr[OHERE][FREQ] = (float)((vc/2) * dz->chwidth); // Central freq of channel
  3015. }
  3016. }
  3017. (*owcnt)++;
  3018. if((dz->flbufptr[OHERE] += dz->wanted) >= dz->flbufptr[OEND]) {
  3019. if((exit_status = write_exact_samps(dz->flbufptr[OBUF],dz->buflen,dz))<0)
  3020. return(exit_status); /* 6 */
  3021. dz->flbufptr[OHERE] = dz->flbufptr[OBUF];
  3022. dz->total_windows_written += SYNCBUFSCNT;
  3023. *owcnt = 0;
  3024. }
  3025. return(FINISHED);
  3026. }
  3027. /*************************** ADVANCE_ALONG_INPUT_WINDOWS ****************************
  3028. *
  3029. * Advance window frame in input.
  3030. * (1) Advance lastwindow to thiswindow.
  3031. * (2) Advance thiswindow to next.
  3032. * (3) If at end of buffer, copy first of buffer-pair window to start of whole buffer i.e. to dz->bigbuf
  3033. * (4) And read more data in AFTER that: i.e. at IBUF.
  3034. * (5) If there are no more windows in source, return FINISHED.
  3035. */
  3036. int advance_along_input_windows(int wdw_to_advance,dataptr dz)
  3037. {
  3038. int n;
  3039. int samps_read;
  3040. for(n=0;n<wdw_to_advance;n++) {
  3041. dz->flbufptr[IHERE] = dz->flbufptr[INEXT]; /* 1 */
  3042. if((dz->flbufptr[INEXT] += dz->wanted) >= dz->flbufptr[OBUF]) { /* 2 */
  3043. memmove((char *)dz->bigfbuf,(char *)dz->flbufptr[IHERE],dz->wanted * sizeof(float));
  3044. dz->flbufptr[IHERE] = dz->bigfbuf; /* 3 */
  3045. dz->flbufptr[INEXT] = dz->flbufptr[IBUF]; /* 4 */
  3046. if((samps_read = fgetfbufEx(dz->flbufptr[INEXT],dz->buflen,dz->ifd[0],0)) < 0) {
  3047. sprintf(errstr,"Can't read samples from input soundfile\n");
  3048. return(SYSTEM_ERROR);
  3049. }
  3050. if(samps_read == 0) /* 5 */
  3051. return FINISHED;
  3052. dz->last_windows_read = dz->total_windows_read;
  3053. dz->total_samps_read += samps_read;
  3054. dz->total_windows_read = dz->total_samps_read/dz->wanted;
  3055. }
  3056. }
  3057. return(CONTINUE);
  3058. }
  3059. /*************************** CREATE_SYNC_BUFFERS ****************************/
  3060. int create_sync_buffers(dataptr dz)
  3061. {
  3062. int n;
  3063. int buffersize;
  3064. if((dz->flbufptr = (float **)malloc(sizeof(float *) * dz->bptrcnt))==NULL) {
  3065. sprintf(errstr,"INSUFFICIENT MEMORY for float sample buffers.\n");
  3066. return(MEMORY_ERROR);
  3067. }
  3068. for(n = 0;n <dz->bptrcnt; n++)
  3069. dz->flbufptr[n] = NULL;
  3070. buffersize = dz->wanted * ((SYNCBUFSCNT * 2) + 2); // Extra windows for (pre)wrap-around of input.
  3071. // 2nd extra window to remember frqs in last window written.
  3072. dz->buflen = SYNCBUFSCNT * dz->wanted; // Normal read & write size is SYNCBUFCNT windows.
  3073. if((dz->bigfbuf = (float*)malloc(buffersize * sizeof(float)))==NULL) {
  3074. sprintf(errstr,"INSUFFICIENT MEMORY for sound buffers.\n");
  3075. return(MEMORY_ERROR);
  3076. }
  3077. // Fixed pointers
  3078. dz->flbufptr[IBUF] = dz->bigfbuf + dz->wanted; // Input buf is offset from bufstart by 1 window, for wrap-around
  3079. dz->flbufptr[OBUF] = dz->flbufptr[IBUF] + (SYNCBUFSCNT * dz->wanted); // Output buf
  3080. dz->flbufptr[OEND] = dz->flbufptr[OBUF] + (SYNCBUFSCNT * dz->wanted); // Last frqs written are stored after OEND
  3081. // Moving pointers
  3082. dz->flbufptr[IHERE] = dz->bigfbuf; // Initial read starts at the pre-wraparound window and reads 1 extra window.
  3083. // After 1st read, last window is wrapped around to dz->bigfbuf. So IHERE is reset to this pre-wrap window.
  3084. dz->flbufptr[INEXT] = dz->flbufptr[IBUF]; // Subsequent reads are to IBUF (1 window after dz->bigfbuf), and INEXT is (re)set to there.
  3085. dz->flbufptr[OHERE] = dz->flbufptr[OBUF]; // Output write pos preset to OBUF start
  3086. return(FINISHED);
  3087. }
  3088. /************************ HANDLE_SYNCDATA *********************
  3089. *
  3090. * 2 columns, 1st if times to sync TO,
  3091. * and 2nd of times in input file which need to be moved (by timestretch)
  3092. * so they coincide with the sync-to times.
  3093. */
  3094. int handle_syncdata(int *cmdlinecnt,char ***cmdline,dataptr dz)
  3095. {
  3096. int linecnt, inlinecnt, cnt;
  3097. char temp[200], *q, *filename = (*cmdline)[0];
  3098. double dummy, lasttotime = -1.0, lastattime = -1.0;
  3099. double *timetosyncto, *timetosyncfrom;
  3100. if(!sloom) {
  3101. if(*cmdlinecnt <= 0) {
  3102. sprintf(errstr,"Insufficient parameters on command line.\n");
  3103. return(USAGE_ONLY);
  3104. }
  3105. }
  3106. if((dz->fp = fopen(filename,"r"))==NULL) {
  3107. sprintf(errstr,"Cannot open datafile %s\n",filename);
  3108. return(DATA_ERROR);
  3109. }
  3110. // COUNT AND TEST INPUT DATA
  3111. cnt = 0;
  3112. linecnt = 0;
  3113. while(fgets(temp,200,dz->fp)!=NULL) {
  3114. q = temp;
  3115. if(is_an_empty_line_or_a_comment(q))
  3116. continue;
  3117. inlinecnt = 0;
  3118. while(get_float_from_within_string(&q,&dummy)) {
  3119. if(dummy < 0.0) {
  3120. sprintf(errstr,"Negative time value (%lf) in sync data.\n",dummy); /* RWD 04/08/20 missing arg dummy */
  3121. return DATA_ERROR;
  3122. }
  3123. if(EVEN(cnt)) {
  3124. if(lasttotime < 0.0)
  3125. lasttotime = dummy;
  3126. else {
  3127. if(dummy <= lasttotime) {
  3128. sprintf(errstr,"Sync-to times (%lf and %lf) do not advance at lines %d and %d\n",lasttotime,dummy,linecnt,linecnt+1);
  3129. return DATA_ERROR;
  3130. }
  3131. lasttotime = dummy;
  3132. }
  3133. } else {
  3134. if(lastattime < 0.0)
  3135. lastattime = dummy;
  3136. else {
  3137. if(dummy <= lastattime) {
  3138. sprintf(errstr,"Sync-from times (%lf and %lf) do not advance at lines %d and %d\n",lastattime,dummy,linecnt,linecnt+1);
  3139. return DATA_ERROR;
  3140. }
  3141. lastattime = dummy;
  3142. }
  3143. }
  3144. inlinecnt++;
  3145. cnt++;
  3146. }
  3147. if(inlinecnt != 2) {
  3148. sprintf(errstr,"Times not paired correctly on line %d\n",linecnt+1);
  3149. return DATA_ERROR;
  3150. }
  3151. linecnt++;
  3152. }
  3153. if(cnt==0) {
  3154. sprintf(errstr,"No data in file %s\n",filename);
  3155. return(DATA_ERROR);
  3156. }
  3157. if(lastattime > dz->duration) {
  3158. sprintf(errstr,"Synchronise-from times reach beyond the end of the input file.\n");
  3159. return(MEMORY_ERROR);
  3160. }
  3161. dz->itemcnt = cnt/2;
  3162. if ((dz->parray = (double **)malloc(2 * sizeof(double *)))==NULL) {
  3163. sprintf(errstr,"Insufficient memory to create syntime data storage.\n");
  3164. return(MEMORY_ERROR);
  3165. }
  3166. if ((dz->parray[0] = (double *)malloc((dz->itemcnt + 2) * sizeof(double)))==NULL) {
  3167. sprintf(errstr,"Insufficient memory to create sync_to times array.\n");
  3168. return(MEMORY_ERROR);
  3169. }
  3170. if ((dz->parray[1] = (double *)malloc((dz->itemcnt + 2) * sizeof(double)))==NULL) {
  3171. sprintf(errstr,"Insufficient memory to create sync_at times array.\n");
  3172. return(MEMORY_ERROR);
  3173. }
  3174. timetosyncto = dz->parray[0];
  3175. timetosyncfrom = dz->parray[1];
  3176. if(fseek(dz->fp,0,0)< 0) {
  3177. sprintf(errstr,"fseek() failed in handle_syncdata()\n");
  3178. return(SYSTEM_ERROR);
  3179. }
  3180. // READ INPUT DATA TO TWO ARRAYS, CONVERTING TIMES TO (possibly fractional) WINDOW-COUNTS
  3181. cnt = 0;
  3182. while(fgets(temp,200,dz->fp)!=NULL) {
  3183. q = temp;
  3184. if(is_an_empty_line_or_a_comment(temp))
  3185. continue;
  3186. while(get_float_from_within_string(&q,&dummy)) {
  3187. if(EVEN(cnt)) {
  3188. *timetosyncto = dummy/dz->frametime; // Converts synctime to (possibly fractional) windowcnts
  3189. timetosyncto++;
  3190. } else {
  3191. *timetosyncfrom = dummy/dz->frametime;
  3192. timetosyncfrom++;
  3193. }
  3194. cnt++;
  3195. }
  3196. }
  3197. if(fclose(dz->fp)<0) {
  3198. fprintf(stdout,"WARNING: Failed to close input textfile %s.\n",filename);
  3199. fflush(stdout);
  3200. }
  3201. (*cmdline)++;
  3202. (*cmdlinecnt)--;
  3203. return(FINISHED);
  3204. }
  3205. /************************ FORCE_WAV_EXTENSION *********************/
  3206. void force_wav_extension(char *filename)
  3207. {
  3208. char *p = filename;
  3209. while(*p != '.') {
  3210. p++;
  3211. if(*p == ENDOFSTR)
  3212. break;
  3213. }
  3214. if(*p == ENDOFSTR)
  3215. strcat(filename,".wav");
  3216. else {
  3217. p++;
  3218. if(*p != 'w') {
  3219. p--;
  3220. *p = ENDOFSTR;
  3221. strcat(filename,".wav");
  3222. }
  3223. }
  3224. }
  3225. /************************************ SPECEX **************************************/
  3226. int specex(dataptr dz)
  3227. {
  3228. int n, k, exit_status, wins_out = 0, wins_read = 0, windows_needed;
  3229. float *obuf = dz->flbufptr[0], *permbuf = dz->flbufptr[1], *obufptr, *obufend, *permwin;
  3230. int samps_read, permcnt, winloc;
  3231. int *perm;
  3232. windows_needed = (int) round(dz->iparam[SPEX_DUR] * dz->param[SPEX_STR]); // Number of Windows generated by stretch
  3233. dz->tempsize = windows_needed; // Windows generated by stretching segment
  3234. if(dz->vflag[0])
  3235. dz->tempsize += dz->iparam[SPEX_TIM]; // If start to be included, include start
  3236. if(dz->vflag[1])
  3237. dz->tempsize += dz->wlength - (dz->iparam[SPEX_TIM] + dz->iparam[SPEX_DUR]);// If end to be included, include end
  3238. dz->tempsize *= dz->wanted;
  3239. obufptr = obuf;
  3240. obufend = permbuf;
  3241. if(dz->vflag[SPEX_STT] && (dz->iparam[SPEX_TIM] > 0)) {
  3242. while(wins_read < dz->iparam[SPEX_TIM]) {
  3243. if((samps_read = fgetfbufEx(obufptr, dz->wanted, dz->ifd[0],0)) < 0) {
  3244. sprintf(errstr,"Failed to read data from input file at time %lf.\n",wins_read * dz->frametime);
  3245. return(SYSTEM_ERROR);
  3246. }
  3247. wins_read++;
  3248. obufptr += dz->wanted;
  3249. if(obufptr >= obufend) {
  3250. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  3251. return(exit_status);
  3252. obufptr = obuf;
  3253. }
  3254. }
  3255. }
  3256. if((samps_read = fgetfbufEx(permbuf, dz->buflen, dz->ifd[0],0)) < 0) {
  3257. sprintf(errstr,"Failed to read data from input file at time %lf.\n",wins_read * dz->frametime);
  3258. return(SYSTEM_ERROR);
  3259. }
  3260. wins_read += dz->buflen/dz->wanted;
  3261. permcnt = dz->iparam[SPEX_DUR]/dz->iparam[SPEX_WIN]; // Forced to be an intiger in parameter-checking
  3262. if((dz->iparray[0] = (int *)malloc(permcnt * sizeof(int)))==NULL) {
  3263. sprintf(errstr,"INSUFFICIENT MEMORY for permutations array.\n");
  3264. return(MEMORY_ERROR);
  3265. }
  3266. perm = dz->iparray[0];
  3267. while(wins_out < windows_needed) {
  3268. rndintperm(perm,permcnt);
  3269. for(n = 0; n < permcnt; n++) {
  3270. winloc = perm[n] * dz->iparam[SPEX_WIN] * dz->wanted; // perm-value * no of windows in permed-groups * size-of-window
  3271. permwin = permbuf + winloc;
  3272. for(k = 0; k < dz->iparam[SPEX_WIN]; k++) { // Copy from this point, the total number of windows in the permed-group
  3273. memcpy((char *)obufptr,(char *)permwin,dz->wanted * sizeof(float));
  3274. permwin += dz->wanted;
  3275. obufptr += dz->wanted;
  3276. if(obufptr >= obufend) {
  3277. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  3278. return(exit_status);
  3279. obufptr = obuf;
  3280. }
  3281. wins_out++;
  3282. if(wins_out >= windows_needed)
  3283. break;
  3284. }
  3285. if(wins_out >= windows_needed)
  3286. break;
  3287. }
  3288. }
  3289. if(dz->vflag[SPEX_END]) {
  3290. samps_read = 1;
  3291. while(samps_read > 0) {
  3292. if((samps_read = fgetfbufEx(obufptr, dz->wanted, dz->ifd[0],0)) < 0) {
  3293. sprintf(errstr,"Failed to read data from input file at time %lf.\n",wins_read * dz->frametime);
  3294. return(SYSTEM_ERROR);
  3295. }
  3296. wins_read++;
  3297. obufptr += dz->wanted;
  3298. if(obufptr >= obufend) {
  3299. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  3300. return(exit_status);
  3301. obufptr = obuf;
  3302. }
  3303. }
  3304. }
  3305. if(obufptr > obuf) {
  3306. if((exit_status = write_samps(obuf,obufptr - obuf,dz))<0)
  3307. return(exit_status);
  3308. }
  3309. return FINISHED;
  3310. }
  3311. /*************************** CREATE_SPECEX_BUFFERS ****************************/
  3312. int create_specex_buffers(dataptr dz)
  3313. {
  3314. long buffersize;
  3315. if((dz->flbufptr = (float **)malloc(sizeof(float *) * dz->bptrcnt))==NULL) {
  3316. sprintf(errstr,"INSUFFICIENT MEMORY for float sample buffers.\n");
  3317. return(MEMORY_ERROR);
  3318. }
  3319. dz->buflen = dz->wanted * dz->iparam[SPEX_DUR]; // Buffer must contain total duration of area to be stretched
  3320. buffersize = dz->buflen * dz->bptrcnt;
  3321. if((dz->bigfbuf = (float *)malloc(buffersize * sizeof(float)))==NULL) {
  3322. sprintf(errstr,"INSUFFICIENT MEMORY for sound buffers.\n");
  3323. return(MEMORY_ERROR);
  3324. }
  3325. dz->flbufptr[0] = dz->bigfbuf;
  3326. dz->flbufptr[1] = dz->bigfbuf + dz->buflen;
  3327. return(FINISHED);
  3328. }
  3329. /*************************** TRANSPART ****************************/
  3330. int transpart(dataptr dz)
  3331. {
  3332. int exit_status;
  3333. int samps_read, wins_read, ccdiv, cctop = 0, ccbot = 0;
  3334. double thistime;
  3335. float *buf = dz->bigfbuf;
  3336. wins_read = 0;
  3337. if((dz->windowbuf = (float **)malloc(sizeof(float *)))==NULL) {
  3338. sprintf(errstr,"INSUFFICIENT MEMORY for spare window array 1.\n");
  3339. return(MEMORY_ERROR);
  3340. }
  3341. if((dz->windowbuf[0] = (float *)malloc(dz->wanted * sizeof(float)))==NULL) {
  3342. sprintf(errstr,"INSUFFICIENT MEMORY for spare window array 2.\n");
  3343. return(MEMORY_ERROR);
  3344. }
  3345. if((samps_read = fgetfbufEx(buf, dz->wanted, dz->ifd[0],0)) < 0) {
  3346. sprintf(errstr,"Failed to read data from input file at time %lf\n",wins_read * dz->frametime);
  3347. return(SYSTEM_ERROR);
  3348. }
  3349. if(dz->mode == 0 || dz->mode == 1 || dz->mode == 4 || dz->mode == 5) {
  3350. if((dz->specenvfrq = (float *)malloc((dz->clength + 1) * sizeof(float)))==NULL) {
  3351. sprintf(errstr,"INSUFFICIENT MEMORY for formant frq array.\n");
  3352. return(MEMORY_ERROR);
  3353. }
  3354. if((dz->specenvpch = (float *)malloc((dz->clength + 1) * sizeof(float)))==NULL) {
  3355. sprintf(errstr,"INSUFFICIENT MEMORY for formant pitch array.\n");
  3356. return(MEMORY_ERROR);
  3357. }
  3358. /*RWD zero the data */
  3359. memset((char *)dz->specenvpch,0,(dz->clength + 1) * sizeof(float));
  3360. if((dz->specenvamp = (float *)malloc((dz->clength + 1) * sizeof(float)))==NULL) {
  3361. sprintf(errstr,"INSUFFICIENT MEMORY for formant aplitude array.\n");
  3362. return(MEMORY_ERROR);
  3363. }
  3364. if((dz->specenvtop = (float *)malloc((dz->clength + 1) * sizeof(float)))==NULL) {
  3365. sprintf(errstr,"INSUFFICIENT MEMORY for formant frq limit array.\n");
  3366. return(MEMORY_ERROR);
  3367. }
  3368. if((exit_status = setup_formants(dz))<0) {
  3369. sprintf(errstr,"Failed to establish formant structure\n");
  3370. return(SYSTEM_ERROR);
  3371. }
  3372. }
  3373. while(samps_read > 0) {
  3374. thistime = wins_read * dz->frametime;
  3375. if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
  3376. return exit_status;
  3377. ccdiv = (int) round(dz->param[1]/dz->chwidth);
  3378. if(EVEN(dz->mode)) { // Above
  3379. ccbot = ccdiv;
  3380. cctop = dz->clength;
  3381. } else { // Below
  3382. ccbot = 0;
  3383. cctop = ccdiv;
  3384. }
  3385. switch(dz->mode) {
  3386. case(0): // fall thro // Keep Formants
  3387. case(1): // fall thro
  3388. case(4): // fall thro
  3389. case(5):
  3390. if((exit_status = spec_keep_formants(ccbot,cctop,dz))<0)
  3391. return exit_status;
  3392. break;
  3393. case(2): // fall thro // Don't Keep Formants
  3394. case(3): // fall thro
  3395. case(6): // fall thro
  3396. case(7):
  3397. if((exit_status = spec_move_formants(ccbot,cctop,dz))<0)
  3398. return exit_status;
  3399. break;
  3400. }
  3401. if((exit_status = write_samps(buf,samps_read,dz))<0)
  3402. return(exit_status);
  3403. if((samps_read = fgetfbufEx(buf, dz->wanted, dz->ifd[0],0)) < 0) {
  3404. sprintf(errstr,"Failed to read data from input file at time %lf\n",wins_read * dz->frametime);
  3405. return(SYSTEM_ERROR);
  3406. }
  3407. wins_read++;
  3408. }
  3409. return FINISHED;
  3410. }
  3411. /********************************** SPEC_KEEP_FORMANTS **********************************
  3412. *
  3413. * transpose spectrum, but retain original spectral envelope.
  3414. */
  3415. int spec_keep_formants(int ccbot,int cctop,dataptr dz)
  3416. {
  3417. int exit_status;
  3418. double pre_totalamp, post_totalamp;
  3419. int cc, vc;
  3420. float *buf = dz->bigfbuf;
  3421. rectify_window(buf,dz);
  3422. if((exit_status = extract_spec_env(0,dz))<0)
  3423. return(exit_status);
  3424. if((exit_status = get_totalamp(&pre_totalamp,buf,dz->wanted))<0)
  3425. return(exit_status);
  3426. switch(dz->mode) {
  3427. case(0): // fall thro // Transpose
  3428. case(1):
  3429. for(cc = ccbot, vc = cc*2; cc < cctop; cc++, vc += 2) {
  3430. if((exit_status = transpose_within_formant_envelope(vc,dz))<0)
  3431. return(exit_status);
  3432. }
  3433. break;
  3434. case(4): // fall thro // Shift
  3435. case(5):
  3436. for(cc = ccbot, vc = cc*2; cc < cctop; cc++, vc += 2) {
  3437. if((exit_status = shift_within_formant_envelope(vc,dz))<0)
  3438. return(exit_status);
  3439. }
  3440. break;
  3441. }
  3442. if((exit_status = re_position_partials_in_appropriate_channels(dz))<0)
  3443. return(exit_status);
  3444. if((exit_status = get_totalamp(&post_totalamp,buf,dz->wanted))<0)
  3445. return(exit_status);
  3446. return specnu_normalise(pre_totalamp,post_totalamp,2,dz);
  3447. }
  3448. /********************************** SPEC_MOVE_FORMANTS **********************************
  3449. *
  3450. * transpose or shift spectrum, (spectral envelope also moves).
  3451. */
  3452. int spec_move_formants(int ccbot,int cctop,dataptr dz)
  3453. {
  3454. int exit_status;
  3455. double pre_totalamp, post_totalamp;
  3456. int cc, vc;
  3457. float *buf = dz->bigfbuf;
  3458. rectify_window(buf,dz);
  3459. if((exit_status = get_totalamp(&pre_totalamp,buf,dz->wanted))<0)
  3460. return(exit_status);
  3461. switch(dz->mode) {
  3462. case(2): // fall thro // Transpose
  3463. case(3):
  3464. for(cc = ccbot, vc = cc*2; cc < cctop; cc++, vc += 2)
  3465. buf[FREQ] = (float)(fabs(buf[FREQ]) * dz->param[1]);
  3466. break;
  3467. case(6): // fall thro // Shift
  3468. case(7):
  3469. for(cc = ccbot, vc = cc*2; cc < cctop; cc++, vc += 2)
  3470. buf[FREQ] = (float)(fabs(buf[FREQ]) + dz->param[1]);
  3471. break;
  3472. }
  3473. if((exit_status = re_position_partials_in_appropriate_channels(dz))<0)
  3474. return(exit_status);
  3475. if((exit_status = get_totalamp(&post_totalamp,buf,dz->wanted))<0)
  3476. return(exit_status);
  3477. return specnu_normalise(pre_totalamp,post_totalamp,2,dz);
  3478. }
  3479. /************************** TRANSPOSE_WITHIN_FORMANT_ENVELOPE *****************************/
  3480. int transpose_within_formant_envelope(int vc,dataptr dz)
  3481. {
  3482. int exit_status;
  3483. double thisspecamp, newspecamp, thisamp, formantamp_ratio;
  3484. float *buf = dz->bigfbuf;
  3485. if((exit_status = getspecenvamp(&thisspecamp,(double)buf[FREQ],0,dz))<0)
  3486. return(exit_status);
  3487. buf[FREQ] = (float)(fabs(buf[FREQ])*dz->param[0]);
  3488. if(buf[FREQ] < dz->nyquist) {
  3489. if(thisspecamp < VERY_TINY_VAL)
  3490. buf[AMPP] = 0.0f;
  3491. else {
  3492. if((exit_status = getspecenvamp(&newspecamp,(double)buf[FREQ],0,dz))<0)
  3493. return(exit_status);
  3494. if(newspecamp < VERY_TINY_VAL)
  3495. buf[AMPP] = 0.0f;
  3496. else {
  3497. formantamp_ratio = newspecamp/thisspecamp;
  3498. if((thisamp = buf[AMPP] * formantamp_ratio) < VERY_TINY_VAL)
  3499. buf[AMPP] = 0.0f;
  3500. else
  3501. buf[AMPP] = (float)thisamp;
  3502. }
  3503. }
  3504. }
  3505. return(FINISHED);
  3506. }
  3507. /************************** SHIFT_TRANSPOSE_WITHIN_FORMANT_ENVELOPE *****************************/
  3508. int shift_within_formant_envelope(int vc,dataptr dz)
  3509. {
  3510. int exit_status;
  3511. double thisspecamp, newspecamp, thisamp, formantamp_ratio;
  3512. float *buf = dz->bigfbuf;
  3513. if((exit_status = getspecenvamp(&thisspecamp,(double)buf[FREQ],0,dz))<0)
  3514. return(exit_status);
  3515. buf[FREQ] = (float)(fabs(buf[FREQ])+dz->param[0]);
  3516. if(buf[FREQ] < dz->nyquist) {
  3517. if(thisspecamp < VERY_TINY_VAL)
  3518. buf[AMPP] = 0.0f;
  3519. else {
  3520. if((exit_status = getspecenvamp(&newspecamp,(double)buf[FREQ],0,dz))<0)
  3521. return(exit_status);
  3522. if(newspecamp < VERY_TINY_VAL)
  3523. buf[AMPP] = 0.0f;
  3524. else {
  3525. formantamp_ratio = newspecamp/thisspecamp;
  3526. if((thisamp = buf[AMPP] * formantamp_ratio) < VERY_TINY_VAL)
  3527. buf[AMPP] = 0.0f;
  3528. else
  3529. buf[AMPP] = (float)thisamp;
  3530. }
  3531. }
  3532. }
  3533. return(FINISHED);
  3534. }
  3535. /************************ RE_POSITION_PARTIALS_IN_APPROPRIATE_CHANNELS *************************
  3536. *
  3537. * (1) At each pass, preset store-buffer channel amps to zero.
  3538. * (2) Move frq data into appropriate channels, carrying the
  3539. * amplitude information along with them.
  3540. * Work down spectrum for upward transposition, and
  3541. * (3) up spectrum for downward transposition,
  3542. * so that we do not overwrite transposed data before we move it.
  3543. * (4) Put new frqs back into src buff.
  3544. */
  3545. int re_position_partials_in_appropriate_channels(dataptr dz)
  3546. {
  3547. int exit_status;
  3548. int truecc,truevc;
  3549. int cc, vc;
  3550. float *buf = dz->bigfbuf;
  3551. for(vc = 0; vc < dz->wanted; vc+=2) /* 1 */
  3552. dz->windowbuf[0][vc] = 0.0f;
  3553. if(dz->param[0] > 1.0f) { /* 2 */
  3554. for(cc=dz->clength-1,vc = dz->wanted-2; cc>=0; cc--, vc-=2) {
  3555. if(buf[FREQ] < dz->nyquist && buf[AMPP] > 0.0f) {
  3556. if((exit_status = get_channel_corresponding_to_frq(&truecc,(double)buf[FREQ],dz))<0)
  3557. return(exit_status);
  3558. truevc = truecc * 2;
  3559. if((exit_status = move_data_into_appropriate_chan(vc,truevc,buf[AMPP],buf[FREQ],dz))<0)
  3560. return(exit_status);
  3561. }
  3562. }
  3563. for(vc = 0; vc < dz->wanted; vc++)
  3564. buf[vc] = dz->windowbuf[0][vc];
  3565. } else if(dz->param[0] < 1.0f){ /* 3 */
  3566. for(cc=0,vc = 0; cc < dz->clength; cc++, vc+=2) {
  3567. if(buf[FREQ] < dz->nyquist && buf[FREQ]>0.0) {
  3568. if((exit_status = get_channel_corresponding_to_frq(&truecc,(double)buf[FREQ],dz))<0)
  3569. return(exit_status);
  3570. truevc = truecc * 2;
  3571. if((exit_status = move_data_into_appropriate_chan(vc,truevc,buf[AMPP],buf[FREQ],dz))<0)
  3572. return(exit_status);
  3573. }
  3574. }
  3575. for(vc = 0; vc < dz->wanted; vc++)
  3576. buf[vc] = dz->windowbuf[0][vc]; /* 4 */
  3577. }
  3578. return(FINISHED);
  3579. }
  3580. /******************* SETUP_FORMANTS *****************/
  3581. int setup_formants(dataptr dz)
  3582. {
  3583. int exit_status;
  3584. int arraycnt;
  3585. aplptr ap = dz->application;
  3586. if((exit_status = establish_formant_band_ranges(dz->infile->channels,ap))<0)
  3587. return(exit_status);
  3588. dz->specenv_type = PICHWISE_FORMANTS;
  3589. dz->formant_bands = 4;
  3590. if((exit_status = initialise_specenv(&arraycnt,dz))<0)
  3591. return(exit_status);
  3592. if((exit_status = set_spec_env_frqs(arraycnt,dz))<0)
  3593. return(exit_status);
  3594. dz->descriptor_samps = dz->infile->specenvcnt * DESCRIPTOR_DATA_BLOKS ;
  3595. return(FINISHED);
  3596. }
  3597. /************************ SET_SPECENV_FRQS ************************
  3598. *
  3599. * FREQWISE BANDS = number of channels for each specenv point
  3600. * PICHWISE BANDS = number of points per octave
  3601. */
  3602. int set_spec_env_frqs(int arraycnt,dataptr dz)
  3603. {
  3604. int exit_status;
  3605. double bandbot;
  3606. double *interval;
  3607. int m, n, k = 0, cc;
  3608. if((exit_status = setup_octave_band_steps(&interval,dz))<0)
  3609. return(exit_status);
  3610. if((exit_status = setup_lo_octave_bands(arraycnt,dz))<0)
  3611. return(exit_status);
  3612. k = TOP_OF_LOW_OCTAVE_BANDS;
  3613. cc = CHAN_ABOVE_LOW_OCTAVES;
  3614. while(cc <= dz->clength) {
  3615. m = 0;
  3616. if((bandbot = dz->chwidth * (double)cc) >= dz->nyquist)
  3617. break;
  3618. for(n=0;n<dz->formant_bands;n++) {
  3619. if(k >= arraycnt) {
  3620. sprintf(errstr,"Formant array too small: set_spec_env_frqs()\n");
  3621. return(PROGRAM_ERROR);
  3622. }
  3623. dz->specenvfrq[k] = (float)(bandbot * interval[m++]);
  3624. dz->specenvpch[k] = (float)log10(dz->specenvfrq[k]);
  3625. dz->specenvtop[k++] = (float)(bandbot * interval[m++]);
  3626. }
  3627. cc *= 2; /* 8-16: 16-32: 32-64 etc as 8vas, then split into bands */
  3628. }
  3629. dz->specenvfrq[k] = (float)dz->nyquist;
  3630. dz->specenvpch[k] = (float)log10(dz->nyquist);
  3631. dz->specenvtop[k] = (float)dz->nyquist;
  3632. dz->specenvamp[k] = (float)0.0;
  3633. k++;
  3634. dz->infile->specenvcnt = k;
  3635. return(FINISHED);
  3636. }
  3637. /************************* SETUP_OCTAVEBAND_STEPS ************************/
  3638. int setup_octave_band_steps(double **interval,dataptr dz)
  3639. {
  3640. double octave_step;
  3641. int n = 1, m = 0, halfbands_per_octave = dz->formant_bands * 2;
  3642. if((*interval = (double *)malloc(halfbands_per_octave * sizeof(double)))==NULL) {
  3643. sprintf(errstr,"INSUFFICIENT MEMORY establishing interval array for formants.\n");
  3644. return(MEMORY_ERROR);
  3645. }
  3646. while(n < halfbands_per_octave) {
  3647. octave_step = (double)n++/(double)halfbands_per_octave;
  3648. (*interval)[m++] = pow(2.0,octave_step);
  3649. }
  3650. (*interval)[m] = 2.0;
  3651. return(FINISHED);
  3652. }
  3653. /************************ SETUP_LOW_OCTAVE_BANDS ***********************
  3654. *
  3655. * Lowest PVOC channels span larger freq steps and therefore we must
  3656. * group them in octave bands, rather than in anything smaller.
  3657. */
  3658. int setup_lo_octave_bands(int arraycnt,dataptr dz)
  3659. {
  3660. int n;
  3661. if(arraycnt < LOW_OCTAVE_BANDS) {
  3662. sprintf(errstr,"Insufficient array space for low_octave_bands\n");
  3663. return(PROGRAM_ERROR);
  3664. }
  3665. for(n=0;n<LOW_OCTAVE_BANDS;n++) {
  3666. switch(n) {
  3667. case(0):
  3668. dz->specenvfrq[0] = (float)1.0; /* frq whose log is 0 */
  3669. dz->specenvpch[0] = (float)0.0;
  3670. dz->specenvtop[0] = (float)dz->chwidth; /* 8VA wide bands */
  3671. break;
  3672. case(1):
  3673. dz->specenvfrq[1] = (float)(dz->chwidth * 1.5); /* Centre Chs 1-2 */
  3674. dz->specenvpch[1] = (float)log10(dz->specenvfrq[1]);
  3675. dz->specenvtop[1] = (float)(dz->chwidth * 2.0);
  3676. break;
  3677. case(2):
  3678. dz->specenvfrq[2] = (float)(dz->chwidth * 3.0); /* Centre Chs 2-4 */
  3679. dz->specenvpch[2] = (float)log10(dz->specenvfrq[2]);
  3680. dz->specenvtop[2] = (float)(dz->chwidth * 4.0);
  3681. break;
  3682. case(3):
  3683. dz->specenvfrq[3] = (float)(dz->chwidth * 6.0); /* Centre Chs 4-8 */
  3684. dz->specenvpch[3] = (float)log10(dz->specenvfrq[3]);
  3685. dz->specenvtop[3] = (float)(dz->chwidth * 8.0);
  3686. break;
  3687. default:
  3688. sprintf(errstr,"Insufficient low octave band setups in setup_lo_octave_bands()\n");
  3689. return(PROGRAM_ERROR);
  3690. }
  3691. }
  3692. return(FINISHED);
  3693. }
  3694. /********************** EXTRACT_SPEC_ENV *******************/
  3695. #define CHAN_SRCHRANGE_F (4)
  3696. int extract_spec_env(int storeno,dataptr dz)
  3697. {
  3698. int n, cc, vc, specenvcnt_less_one;
  3699. int botchan, topchan;
  3700. double botfreq, topfreq;
  3701. double bwidth_in_chans;
  3702. float *ampstore, *buf = dz->bigfbuf;
  3703. switch(storeno) {
  3704. case(0): ampstore = dz->specenvamp; break;
  3705. case(1): ampstore = dz->specenvamp2; break;
  3706. default:
  3707. sprintf(errstr,"Unknown storenumber in extract_spec_env()\n");
  3708. return(PROGRAM_ERROR);
  3709. }
  3710. specenvcnt_less_one = dz->infile->specenvcnt - 1;
  3711. vc = 0;
  3712. for(n=0;n<dz->infile->specenvcnt;n++)
  3713. ampstore[n] = (float)0.0;
  3714. topfreq = 0.0f;
  3715. n = 0;
  3716. while(n < specenvcnt_less_one) {
  3717. botfreq = topfreq;
  3718. botchan = (int)((botfreq + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */
  3719. botchan -= CHAN_SRCHRANGE_F;
  3720. botchan = max(botchan,0);
  3721. topfreq = dz->specenvtop[n];
  3722. topchan = (int)((topfreq + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */
  3723. topchan += CHAN_SRCHRANGE_F;
  3724. topchan = min(topchan,dz->clength);
  3725. for(cc = botchan,vc = botchan * 2; cc < topchan; cc++,vc += 2) {
  3726. if(buf[FREQ] >= botfreq && buf[FREQ] < topfreq)
  3727. ampstore[n] = (float)(ampstore[n] + buf[AMPP]);
  3728. }
  3729. bwidth_in_chans = (double)(topfreq - botfreq)/dz->chwidth;
  3730. ampstore[n] = (float)(ampstore[n]/bwidth_in_chans);
  3731. n++;
  3732. }
  3733. return(FINISHED);
  3734. }
  3735. /******************* MOVE_DATA_INTO_APPROPRIATE_CHANNEL *****************
  3736. *
  3737. * If there turns out to be more than one partial to a channel,
  3738. * keep partial that was loudest in orig sound, retaining its
  3739. * loudness for further comparison.
  3740. */
  3741. int move_data_into_appropriate_chan(int vc,int truevc,float thisamp,float thisfrq,dataptr dz)
  3742. {
  3743. float *buf = dz->bigfbuf;
  3744. if(buf[AMPP] > dz->windowbuf[0][truevc]) {
  3745. dz->windowbuf[0][truevc++] = thisamp;
  3746. dz->windowbuf[0][truevc] = thisfrq;
  3747. }
  3748. return(FINISHED);
  3749. }
  3750. /**************************** SPECNU_NORMALISE ***************************/
  3751. int specnu_normalise(double pre_totalamp,double post_totalamp,int paramno,dataptr dz)
  3752. {
  3753. double normaliser;
  3754. int vc;
  3755. float *buf = dz->bigfbuf;
  3756. if(post_totalamp < VERY_TINY_VAL) {
  3757. if(!dz->zeroset) {
  3758. fprintf(stdout,"WARNING: Zero-amp spectral window(s) encountered: orig window(s) substituted.\n");
  3759. fflush(stdout);
  3760. dz->zeroset = TRUE;
  3761. }
  3762. } else {
  3763. normaliser = pre_totalamp/post_totalamp; /* REMOVED a multiplier of 0.5 : APRIL 1998 */
  3764. for(vc = 0; vc < dz->wanted; vc += 2)
  3765. buf[AMPP] = (float)(buf[AMPP] * normaliser * dz->param[paramno]);
  3766. }
  3767. return(FINISHED);
  3768. }
  3769. /*************************** NUINVERT ****************************/
  3770. int nuinvert(dataptr dz)
  3771. {
  3772. int exit_status;
  3773. int samps_read, wins_read, cctop, ccpk,ccbot;
  3774. double thistime;
  3775. float *buf = dz->bigfbuf;
  3776. ccbot = (int)round(dz->param[INV_BOT]/dz->chwidth); // Lowest channel in inversion
  3777. cctop = (int)round(dz->param[INV_TOP]/dz->chwidth); // Highest channel in inversion
  3778. ccpk = (int)round(dz->param[INV_PKTOP]/dz->chwidth); // Range of entire spectrum in which to search for peak
  3779. wins_read = 0;
  3780. if((samps_read = fgetfbufEx(buf, dz->wanted, dz->ifd[0],0)) < 0) {
  3781. sprintf(errstr,"Failed to read data from input file at time %lf\n",wins_read * dz->frametime);
  3782. return(SYSTEM_ERROR);
  3783. }
  3784. while(samps_read > 0) {
  3785. thistime = wins_read * dz->frametime;
  3786. if((exit_status = invert_spectrum(ccbot,cctop,ccpk,wins_read,dz))<0)
  3787. return(exit_status);
  3788. if((exit_status = write_samps(buf,samps_read,dz))<0)
  3789. return(exit_status);
  3790. if((samps_read = fgetfbufEx(buf, dz->wanted, dz->ifd[0],0)) < 0) {
  3791. sprintf(errstr,"Failed to read data from input file at time %lf\n",wins_read * dz->frametime);
  3792. return(SYSTEM_ERROR);
  3793. }
  3794. wins_read++;
  3795. }
  3796. return FINISHED;
  3797. }
  3798. /********************************** INVERT_SPECTRUM **********************************
  3799. *
  3800. * Invert spectrum, but retain original spectral envelope.
  3801. */
  3802. int invert_spectrum(int ccbot,int cctop,int ccpk,int wins_read,dataptr dz)
  3803. {
  3804. int exit_status, botmaxloc, topmaxloc;
  3805. float maxamplo = 0.0, maxamphi = 0.0, maxamp = 0.0, minamp = 0.0, amprange;
  3806. float *buf = dz->bigfbuf;
  3807. rectify_window(buf,dz);
  3808. if((exit_status = find_maxamp_channel(ccbot,cctop,&maxamp,dz))<0) // maximum level in inverted section
  3809. return FINISHED;
  3810. if(maxamp < FLTERR) // No spectral data to invert
  3811. return FINISHED;
  3812. if((exit_status = find_minamp_channel(ccbot,cctop,&minamp,dz))<0) // minimum level in inverted section
  3813. return FINISHED;
  3814. amprange = maxamp - minamp;
  3815. if((botmaxloc = find_maxamp_channel(0,ccpk,&maxamplo,dz))<0) // maximum level in bottom part of entire spectrum
  3816. return FINISHED; // Data too low level to invert
  3817. topmaxloc = cctop - 1;
  3818. maxamphi = buf[topmaxloc * 2];
  3819. if((exit_status = create_contours(maxamplo,maxamphi,botmaxloc,topmaxloc,cctop,dz))<0)
  3820. return(exit_status);
  3821. if((exit_status = do_spectral_invert(ccbot,cctop,amprange,minamp,dz))<0)
  3822. return(exit_status);
  3823. return FINISHED;
  3824. }
  3825. /********************************** FIND_MINAMP_CHANNEL ***********************************/
  3826. int find_minamp_channel(int cclo,int cchi,float *minamp,dataptr dz)
  3827. {
  3828. int cc, vc, maxloc;
  3829. float *buf = dz->bigfbuf;
  3830. *minamp = MAXFLOAT;
  3831. maxloc = -1;
  3832. for(cc = cclo, vc = cc*2; cc < cchi; cc++, vc += 2) {
  3833. if(buf[AMPP] < *minamp) {
  3834. *minamp = buf[AMPP];
  3835. maxloc = cc;
  3836. }
  3837. }
  3838. return maxloc;
  3839. }
  3840. /********************************** CREATE_CONTOURS **********************************
  3841. *
  3842. * pk top of top of
  3843. * lo inversion spectrum
  3844. * -x--o | |
  3845. * | A \ B |-----------|
  3846. * | \ | |
  3847. * bottom of o |
  3848. * inversion pk |
  3849. * | hi |
  3850. * | |
  3851. * CONTOUR |Unaffected |
  3852. */
  3853. int create_contours(float maxamplo,float maxamphi,int botmaxloc,int topmaxloc,int cctop,dataptr dz)
  3854. {
  3855. int cc, vc, n, locdiff;
  3856. float *buf2 = dz->flbufptr[2];
  3857. double ratio, ampdiff, ampstep;
  3858. ampdiff = maxamphi - maxamplo;
  3859. locdiff = topmaxloc - botmaxloc;
  3860. memset((char *)buf2,0,dz->wanted * sizeof(float));
  3861. for(cc = 0, vc = 0; cc < botmaxloc; cc++, vc +=2) // A
  3862. buf2[AMPP] = maxamplo;
  3863. for(cc = botmaxloc, vc = cc*2,n = 0; cc <= topmaxloc; cc++,vc +=2,n++) { // B
  3864. ratio = (double)n/(double)locdiff;
  3865. ampstep = ampdiff * ratio;
  3866. buf2[AMPP] = (float)(maxamplo + ampstep);
  3867. }
  3868. return FINISHED;
  3869. }
  3870. /**************************************** DO_SPECTRAL_INVERT *********************
  3871. *
  3872. * (1) Find level in channels RELATIVE TO the contour
  3873. * chanamp/contouramp
  3874. * (2) Invert the order of the RELATIVE-AMPLITUDES
  3875. * (3) Establish now TRUE amplitude
  3876. * by multiplying relative-amplitude by inverted contour.
  3877. */
  3878. int do_spectral_invert(int ccbot,int cctop,float amprange,float minamp,dataptr dz)
  3879. {
  3880. int exit_status, cc, vc, vc2;
  3881. int vctop = (cctop-1)*2; // Last active amplitude channel in area being inverted
  3882. int halfway = (ccbot + cctop)/2;
  3883. float temp, numaxamp = 0.0, numinamp = 0.0;
  3884. double ampratio;
  3885. float *buf = dz->bigfbuf, *buf2 = dz->flbufptr[2];
  3886. for(cc = ccbot, vc = cc*2; cc < cctop; cc++, vc +=2) // Find chanamp relative to contour
  3887. buf[AMPP] = (float)(buf[AMPP]/buf2[AMPP]); // chanamp/contouramp (contouramp vals cannot be zero)
  3888. for(cc = ccbot, vc = cc*2,vc2 = vctop; cc < halfway; cc++, vc +=2, vc2 -=2) {
  3889. temp = buf[vc]; // Invert order of amplitude-ratios
  3890. buf[vc] = buf[vc2];
  3891. buf[vc2] = temp;
  3892. }
  3893. for(cc = ccbot, vc = cc*2; cc < cctop; cc++, vc +=2) // Find true amp from relative amp, now relative to contour
  3894. buf[AMPP] = (float)(buf[AMPP]*buf2[AMPP]); // relative-contouramp * contour
  3895. if((exit_status = find_maxamp_channel(ccbot,cctop,&numaxamp,dz))<0) {
  3896. sprintf(errstr,"Failed to find maximum amplitude after inversion\n");
  3897. return PROGRAM_ERROR;
  3898. }
  3899. if((exit_status = find_minamp_channel(ccbot,cctop,&numinamp,dz))<0) {
  3900. sprintf(errstr,"Failed to find minimum amplitude after inversion\n");
  3901. return PROGRAM_ERROR;
  3902. }
  3903. ampratio = amprange/(numaxamp - numinamp);
  3904. for(cc = ccbot, vc = cc*2; cc < cctop; cc++, vc +=2) // Scale output within range of input
  3905. buf[AMPP] = (float)((((buf[AMPP] - numinamp) * ampratio) + minamp) * dz->param[INV_GAIN]);
  3906. return FINISHED;
  3907. }
  3908. /********************************** FIND_MAXAMP_CHANNEL ***********************************/
  3909. int find_maxamp_channel(int cclo,int cchi,float *maxamp,dataptr dz)
  3910. {
  3911. int cc, vc, maxloc;
  3912. float *buf = dz->bigfbuf;
  3913. *maxamp = 0.0;
  3914. maxloc = -1;
  3915. for(cc = cclo, vc = cc*2; cc < cchi; cc++, vc += 2) {
  3916. if(buf[AMPP] > *maxamp) {
  3917. *maxamp = buf[AMPP];
  3918. maxloc = cc;
  3919. }
  3920. }
  3921. return maxloc;
  3922. }
  3923. /**************************** ALLOCATE_QUAD_BUFFER ******************************/
  3924. int allocate_quad_buffer(dataptr dz)
  3925. {
  3926. unsigned int buffersize;
  3927. if(dz->bptrcnt < 6) {
  3928. sprintf(errstr,"Insufficient bufptrs established in allocate_triple_buffer()\n");
  3929. return(PROGRAM_ERROR);
  3930. }
  3931. //TW REVISED: buffers don't need to be multiples of secsize
  3932. buffersize = dz->wanted;
  3933. dz->buflen = buffersize;
  3934. if((dz->bigfbuf = (float*)malloc(dz->buflen*4 * sizeof(float)))==NULL) {
  3935. sprintf(errstr,"INSUFFICIENT MEMORY for sound buffers.\n");
  3936. return(MEMORY_ERROR);
  3937. }
  3938. dz->big_fsize = dz->buflen;
  3939. dz->flbufptr[2] = dz->bigfbuf + dz->big_fsize;
  3940. dz->flbufptr[3] = dz->flbufptr[2] + dz->big_fsize;
  3941. dz->flbufptr[4] = dz->flbufptr[3] + dz->big_fsize;
  3942. dz->flbufptr[5] = dz->flbufptr[4] + dz->big_fsize;
  3943. return(FINISHED);
  3944. }
  3945. /*************************** CONVOLVE ****************************/
  3946. int convolve(dataptr dz)
  3947. {
  3948. int exit_status, passno = 1;
  3949. int samps_read, samps_read2;
  3950. double maxin = 0.0, maxout = 0.0, ubermaxin = -HUGE, ubermaxout = -HUGE;
  3951. float *buf = dz->bigfbuf, *buflast = NULL, *buf2 = NULL, *buf2last = NULL;
  3952. int wins_read;
  3953. double ratio, ratiosum;
  3954. while(passno <= 2) {
  3955. wins_read = 0;
  3956. ratiosum = 0.0;
  3957. dz->total_samps_read = 0;
  3958. if(passno == 1)
  3959. fprintf(stdout,"First pass : Assessing output level.\n");
  3960. else {
  3961. if((sndseekEx(dz->ifd[0],0,0)<0)){
  3962. sprintf(errstr,"sndseek() failed to Seek to start of file-1 for 2nd pass\n");
  3963. return SYSTEM_ERROR;
  3964. } // 2nd pass : Seek to start of files
  3965. if(dz->mode == 1) {
  3966. if((sndseekEx(dz->ifd[1],0,0)<0)){
  3967. sprintf(errstr,"sndseek() failed to Seek to start of file-2 for 2nd pass\n");
  3968. return SYSTEM_ERROR;
  3969. }
  3970. }
  3971. maxin = ubermaxin; // 2nd pass : set maxin,out sent to OVERALL max vals
  3972. maxout = ubermaxout; // And send to proceeses, to do normalisation
  3973. fprintf(stdout,"Second pass : Scaling data and creating output.\n");
  3974. }
  3975. fflush(stdout);
  3976. if((samps_read = fgetfbufEx(buf, dz->wanted, dz->ifd[0],0)) < 0) {
  3977. sprintf(errstr,"Failed to read data from input file at time %lf\n",wins_read * dz->frametime);
  3978. return(SYSTEM_ERROR);
  3979. }
  3980. if(dz->mode == 1) {
  3981. if(passno == 1) {
  3982. buflast = dz->flbufptr[2];
  3983. buf2 = dz->flbufptr[3];
  3984. buf2last = dz->flbufptr[4];
  3985. memset((char *)buflast, 0,dz->wanted * sizeof(float)); // Initialise window memory buffers to zero
  3986. memset((char *)buf2last,0,dz->wanted * sizeof(float));
  3987. ratio = (double)dz->insams[0]/(double)dz->insams[1];
  3988. }
  3989. if((samps_read2 = fgetfbufEx(buf, dz->wanted, dz->ifd[0],0)) < 0) {
  3990. sprintf(errstr,"Failed to read data from input file at time %lf\n",wins_read * dz->frametime);
  3991. return(SYSTEM_ERROR);
  3992. }
  3993. }
  3994. while(samps_read > 0) {
  3995. switch(dz->mode) {
  3996. case(0):
  3997. if((exit_status = self_convolve(buf,&wins_read,&ratio,&ratiosum,&maxin,&maxout,passno,dz))<0)
  3998. return(exit_status);
  3999. break;
  4000. case(1):
  4001. if((exit_status = do_convolve(buf,buflast,buf2,buf2last,&wins_read,&ratio,&ratiosum,&maxin,&maxout,passno,dz))<0)
  4002. return(exit_status);
  4003. break;
  4004. }
  4005. if(passno == 1) { // Calculate max window levels, on input & output, over entire sound
  4006. ubermaxin = max(maxin, ubermaxin);
  4007. ubermaxout = max(maxout,ubermaxout);
  4008. } else { // Write samples only on 2nd pass
  4009. if((exit_status = write_samps(buf,samps_read,dz))<0)
  4010. return(exit_status);
  4011. }
  4012. if((samps_read = fgetfbufEx(buf, dz->wanted, dz->ifd[0],0)) < 0) {
  4013. sprintf(errstr,"Failed to read data from input file at time %lf\n",wins_read * dz->frametime);
  4014. return(SYSTEM_ERROR);
  4015. }
  4016. wins_read++;
  4017. }
  4018. passno++;
  4019. }
  4020. return FINISHED;
  4021. }
  4022. /**************************** SELF_CONVOLVE ******************************/
  4023. int self_convolve(float *buf,int *wins_read,double *ratio,double *ratiosum,double *maxin,double *maxout,int passno,dataptr dz)
  4024. {
  4025. int exit_status, n, cc, vc;
  4026. double val;
  4027. rectify_window(buf,dz);
  4028. if(passno == 1) {
  4029. *maxin = -HUGE; // In PASS 1, record max window amplitude, on input and output,
  4030. *maxout = -HUGE; // to return to calling routine.
  4031. for(cc=0, vc = 0; cc < dz->clength; cc++,vc+=2) {
  4032. val = buf[AMPP];
  4033. *maxin = max(*maxin,buf[AMPP]);
  4034. for(n=0;n<dz->iparam[1];n++) // Multiply the amplitude by itself (param[1] times)
  4035. val *= buf[AMPP];
  4036. buf[AMPP] = (float)val;
  4037. *maxout = max(*maxout,buf[AMPP]);
  4038. }
  4039. } else {
  4040. for(cc=0, vc = 0; cc < dz->clength; cc++,vc+=2) {
  4041. val = buf[AMPP];
  4042. for(n=0;n<dz->iparam[1];n++)
  4043. val *= buf[AMPP];
  4044. buf[AMPP] = (float)val;
  4045. }
  4046. if((exit_status = specnu_normalise(*maxin,*maxout,0,dz))<0)
  4047. return exit_status;
  4048. }
  4049. return FINISHED;
  4050. }
  4051. /**************************** DO_CONVOLVE ******************************/
  4052. int do_convolve(float *buf,float *buflast,float *buf2,float *buf2last,int *wins_read,double *ratio,double *ratiosum,
  4053. double *maxin,double *maxout,int passno,dataptr dz)
  4054. {
  4055. int exit_status, n, samps_read, cc ,vc;
  4056. double aval, fval, fbot, ftop;
  4057. double fbufdif1, fbufdif2, fdifsum;
  4058. rectify_window(buf,dz);
  4059. if(dz->vflag[0]) {
  4060. if((samps_read = fgetfbufEx(buf2, dz->wanted, dz->ifd[1],0)) < 0) {
  4061. sprintf(errstr,"Failed to read data from 2nd input file at time %lf\n",*wins_read * dz->frametime);
  4062. return(SYSTEM_ERROR);
  4063. }
  4064. rectify_window(buf2,dz);
  4065. if(samps_read == 0) {
  4066. memset((char *)buf2,0,dz->wanted * sizeof(float));
  4067. }
  4068. } else {
  4069. if(*ratiosum >= *wins_read) { // Only read 2nd file when 1st file has advanced to requisite no of windows
  4070. if((samps_read = fgetfbufEx(buf2, dz->wanted, dz->ifd[1],0)) < 0) {
  4071. sprintf(errstr,"Failed to read data from 2nd input file at time %lf\n",*wins_read * dz->frametime);
  4072. return(SYSTEM_ERROR);
  4073. }
  4074. rectify_window(buf2,dz);
  4075. *ratiosum += *ratio; // Find next 1st-file-input-window-number at which we'll next read 2nd file
  4076. }
  4077. }
  4078. fbot = -dz->halfchwidth;
  4079. ftop = dz->halfchwidth;
  4080. if(passno == 1) {
  4081. *maxin = -HUGE; // In PASS 1, record max window amplitude, on input and output,
  4082. *maxout = -HUGE; // to return to calling routine.
  4083. for(cc=0, vc = 0; cc < dz->clength; cc++,vc+=2) {
  4084. aval = buf[AMPP];
  4085. *maxin = max(*maxin,buf[AMPP]);
  4086. fval = buflast[FREQ]; // We will advance frq in PREVIOUS input window, but differently
  4087. fbufdif1 = buf[FREQ] - buflast[FREQ]; // frq advance of 1st file to reach this channel
  4088. fbufdif2 = buf2[FREQ] - buf2last[FREQ]; // frq advance of 2nd file to reach this channel
  4089. fdifsum = fbufdif1 + fbufdif2; // Sum these (akin to summing phase)
  4090. for(n=0;n<dz->iparam[1];n++) {
  4091. aval *= buf2[AMPP]; // multiply the amps
  4092. fval += fdifsum; // advance previous channels freq by the new ammount ("sum phase")
  4093. fdifsum += fbufdif2; // In case process is to be repeated,
  4094. } // advance by 2nd file's increment, again,
  4095. fval = chanadjust(fval,fbot,ftop,dz); // Force output frqs into their original channels
  4096. fbot += dz->chwidth; // advance frq-limits to those of next channel
  4097. ftop += dz->chwidth;
  4098. buf[AMPP] = (float)aval; // output new values
  4099. buf[FREQ] = (float)fval;
  4100. buflast[FREQ] = buf[FREQ]; // Store cuurent values for next window calculations
  4101. buf2last[FREQ] = buf2[FREQ];
  4102. *maxout = max(*maxout,buf[AMPP]);
  4103. }
  4104. } else {
  4105. for(cc=0, vc = 0; cc < dz->clength; cc++,vc+=2) {
  4106. aval = buf[AMPP]; // In PASS 2, use window maximum IN ENTIRE FILE, on input & output,
  4107. fval = buflast[FREQ]; // Passed back into this process by calling routine ,
  4108. fbufdif1 = buf[FREQ] - buflast[FREQ]; // To scale the output.
  4109. fbufdif2 = buf2[FREQ] - buf2last[FREQ];
  4110. fdifsum = fbufdif1 + fbufdif2;
  4111. for(n=0;n<dz->iparam[1];n++) {
  4112. aval *= buf2[AMPP];
  4113. fval += fdifsum;
  4114. fdifsum += fbufdif2;
  4115. }
  4116. fval = chanadjust(fval,fbot,ftop,dz);
  4117. fbot += dz->chwidth;
  4118. ftop += dz->chwidth;
  4119. buf[AMPP] = (float)aval;
  4120. buf[FREQ] = (float)fval;
  4121. buflast[FREQ] = buf[FREQ];
  4122. buf2last[FREQ] = buf2[FREQ];
  4123. }
  4124. if((exit_status = specnu_normalise(*maxin,*maxout,0,dz))<0)
  4125. return exit_status;
  4126. }
  4127. return FINISHED;
  4128. }
  4129. /************************************ CHANADJUST *********************************
  4130. *
  4131. * If frq outside its allotted channel, refelct off top and bottom till it's within channel,
  4132. *
  4133. * IN NEXT CHAN ABOVE EVEN NO OF CHANS ABOVE
  4134. * True 0 True 0 1 2
  4135. * Frq ABOVE the channel limits | |->x | | |-------|-------|->x |
  4136. * How many channels above?
  4137. * If 0 (next channel) just invert | x<-| | |<------|
  4138. * OR if EVEN number of chans |------>|
  4139. * bouce off top | x<-|
  4140. *
  4141. * ODD NO OF CHANS ABOVE
  4142. * True 0 1
  4143. * If ODD number of chans, | |-------|->x |
  4144. * bounce off bottom.
  4145. * |<------|
  4146. * |->x |
  4147. *
  4148. * IN NEXT CHAN BELOW EVEN NO OF CHANS BELOW
  4149. * 0 True 2 1 0 True
  4150. * Frq BELOW the channel limits | x<-| | | x<-|-------|-------| |
  4151. * How many channels below?
  4152. * If 0 (next channel) just invert | |->x | |------>|
  4153. * OR if EVEN number of chans |<------|
  4154. * bouce off top |->x |
  4155. *
  4156. * ODD NO OF CHANS BELOW
  4157. * 1 0 True
  4158. * If ODD number of chans, | x<-|-------| |
  4159. * bounce off top.
  4160. * |------>|
  4161. * | <-x|
  4162. */
  4163. double chanadjust(double frq,double fbot,double ftop,dataptr dz)
  4164. {
  4165. double ovflow, val;
  4166. int chanxs;
  4167. if((ovflow = frq - ftop) > 0.0) { // Frq above the channel limits
  4168. chanxs = (int)floor(ovflow/dz->chwidth);// How many channels above?
  4169. if(EVEN(chanxs)) // If EVEN just bounce off top
  4170. val = ftop - ovflow; //
  4171. else // Else bounce of bottom
  4172. val = fbot + ovflow; //
  4173. } else if((ovflow = frq - fbot) < 0.0) { // Frq below channel limits
  4174. ovflow = -ovflow;
  4175. chanxs = (int)floor(ovflow/dz->chwidth);// How many channels below?
  4176. if(EVEN(chanxs))
  4177. val = fbot + ovflow; // If EVEN just bounce off bottom
  4178. else
  4179. val = ftop - ovflow; // Else bounce of top
  4180. } else
  4181. val = frq;
  4182. if(val < 0.0) // check still within total range
  4183. val = -val;
  4184. if(val > dz->nyquist)
  4185. val = dz->nyquist - val;
  4186. return val;
  4187. }
  4188. /*************************************** SPECSND **************************/
  4189. int specsnd(dataptr dz)
  4190. {
  4191. int exit_status;
  4192. float *buf = dz->bigfbuf, *obuf = dz->flbufptr[2];
  4193. int obufcnt = 0, positive = 1;
  4194. long samps_read, wins_read = 0;
  4195. double transrange;
  4196. dz->param[0] = pow(2.0,dz->iparam[0]); // Convert oct tranpos to transpos ratios
  4197. dz->param[1] = pow(2.0,dz->iparam[1]);
  4198. transrange = dz->param[1] - dz->param[0];
  4199. if((samps_read = fgetfbufEx(buf, dz->wanted, dz->ifd[0],0)) < 0) {
  4200. sprintf(errstr,"Failed to read data from input file at time %lf\n",wins_read * dz->frametime);
  4201. return(SYSTEM_ERROR);
  4202. }
  4203. while(samps_read > 0) {
  4204. if((exit_status = do_specsnd(&obufcnt,positive,dz->param[0],transrange,dz))<0)
  4205. return(exit_status);
  4206. positive = -positive;
  4207. if((exit_status = write_samps(obuf,obufcnt,dz))<0)
  4208. return(exit_status);
  4209. if((samps_read = fgetfbufEx(buf, dz->wanted, dz->ifd[0],0)) < 0) {
  4210. sprintf(errstr,"Failed to read data from input file at time %lf\n",wins_read * dz->frametime);
  4211. return(SYSTEM_ERROR);
  4212. }
  4213. wins_read++;
  4214. }
  4215. return FINISHED;
  4216. }
  4217. /***************************************** DO_SPECSND ********************************
  4218. *
  4219. * Find MEan of spectrum | /\
  4220. * |_/__\/\________
  4221. * |/ \/\
  4222. * |__________\__
  4223. *
  4224. *
  4225. * |
  4226. * Subtract meanspectrum | /\
  4227. * |_/__\/\________
  4228. * |/ \/\
  4229. * | \
  4230. *
  4231. * Contract to duration of input sound, taking into account decimation
  4232. * Write as sound.
  4233. */
  4234. int do_specsnd(int *obufcnt,int positive,double transbot,double transrange,dataptr dz)
  4235. {
  4236. float *buf = dz->bigfbuf, *obuf = dz->flbufptr[2];
  4237. int cc, vc, j, k = 0;
  4238. double sum = 0.0, maxsamp = -HUGE, pratio, pratio_step;
  4239. rectify_window(buf,dz);
  4240. k = 0;
  4241. for(cc=0, vc = 0; cc < dz->clength; cc++,vc+=2)
  4242. maxsamp = max(maxsamp,buf[AMPP]);
  4243. pratio = (transrange * maxsamp) + transbot;
  4244. pratio_step = pratio;
  4245. *obufcnt = 0;
  4246. k = 0;
  4247. j = 0;
  4248. for(cc=0, vc = 0; cc < dz->clength; cc++,vc+=2) {
  4249. sum += buf[AMPP];
  4250. j++;
  4251. if(++k >= pratio_step) {
  4252. sum /= pratio;
  4253. sum = min(sum,0.95);
  4254. obuf[*obufcnt] = (float)(sum * positive);
  4255. (*obufcnt)++;
  4256. pratio_step += pratio;
  4257. sum = 0.0;
  4258. j = 0;
  4259. }
  4260. }
  4261. if(j > 0) {
  4262. sum /= pratio;
  4263. obuf[*obufcnt] = (float)(sum * positive);
  4264. (*obufcnt)++;
  4265. }
  4266. return FINISHED;
  4267. }
  4268. /**************************** CREATE_SPECFRAC_BUFFERS ******************************/
  4269. int create_specfrac_buffers(dataptr dz)
  4270. {
  4271. unsigned int buffersize;
  4272. if(dz->bptrcnt < 3) {
  4273. sprintf(errstr,"Insufficient bufptrs established in allocate_triple_buffer()\n");
  4274. return(PROGRAM_ERROR);
  4275. }
  4276. buffersize = dz->insams[0] * 3;
  4277. dz->buflen = dz->insams[0];
  4278. if((dz->bigfbuf = (float*)malloc(buffersize * sizeof(float)))==NULL) {
  4279. sprintf(errstr,"INSUFFICIENT MEMORY for sound buffers.\n");
  4280. return(MEMORY_ERROR);
  4281. }
  4282. dz->big_fsize = dz->buflen;
  4283. dz->flbufptr[0] = dz->bigfbuf;
  4284. dz->flbufptr[1] = dz->bigfbuf + dz->buflen;
  4285. dz->flbufptr[2] = dz->flbufptr[2] + (dz->buflen * 2); // 2nd buffer is double size of first
  4286. return(FINISHED);
  4287. }
  4288. /**************************** CHECK_FRACTAL_PARAM_VALIDITY_AND_CONSISTENCY *****************************/
  4289. int check_fractal_param_validity_and_consistency(dataptr dz)
  4290. {
  4291. int minfracsize, maxsegcnt, maxcutcnt;
  4292. minfracsize = 1;
  4293. maxsegcnt = dz->wlength - 1; // Number of segments obtained by cutting file into single windows
  4294. maxcutcnt = 1;
  4295. dz->maxfraccnt = 2; // Count how many successive cuts-in-half are needed
  4296. while(dz->maxfraccnt < maxsegcnt) { // To generate NO MORE THAN maxfraccnt segments.
  4297. dz->maxfraccnt *= 2;
  4298. maxcutcnt++; // calculate the maximum number of divisions by 2
  4299. } // which will fit INSIDE the maxsegcnt
  4300. if(dz->mode < 6)
  4301. dz->maxfraccnt /= 2;
  4302. dz->copycnt = dz->maxfraccnt; // TOTAL number of windows to be copied in each processing call
  4303. dz->itemcnt = dz->maxfraccnt + 1; // Total number of windows to eventually be written out (includes window 0)
  4304. // AND HIGHEST window NUMBER in write-buf to be written to (includes window 0)
  4305. maxcutcnt--;
  4306. switch(dz->mode) {
  4307. case(6): //fall thro
  4308. case(7): //fall thro
  4309. case(8):
  4310. maxcutcnt--;
  4311. break;
  4312. }
  4313. if(dz->iparam[FRACDEPTH] > maxcutcnt) {
  4314. sprintf(errstr,"INFO: Maximum number of fractal cuts for this file = %d\n",maxcutcnt);
  4315. return DATA_ERROR;
  4316. }
  4317. return FINISHED;
  4318. }
  4319. /**************************** SPECFRAC *****************************/
  4320. int specfrac(dataptr dz)
  4321. {
  4322. int exit_status;
  4323. int samps_read;
  4324. if(!dz->vflag[0]) {
  4325. dz->process_type = BIG_ANALFILE;
  4326. dz->outfiletype = ANALFILE_OUT;
  4327. if((exit_status = create_sized_outfile(dz->outfilename,dz))<0)
  4328. return(exit_status);
  4329. }
  4330. if((samps_read = fgetfbufEx(dz->flbufptr[0], dz->insams[0], dz->ifd[0],0)) < 0) {
  4331. sprintf(errstr,"Failed to read data from input file\n");
  4332. return(SYSTEM_ERROR);
  4333. }
  4334. memset((char *)dz->flbufptr[1],0,dz->insams[0] * sizeof(float));
  4335. switch(dz->mode) {
  4336. case(0): // Fractal copy and shrink
  4337. if((exit_status = fractal_copy_and_shrink(dz))<0)
  4338. return exit_status;
  4339. break;
  4340. case(1): // Fractal reverse-copy and shrink by interpolation
  4341. if((exit_status = fractal_reverse_copy_and_shrink(dz))<0)
  4342. return exit_status;
  4343. break;
  4344. case(2): //fall thro // Fractal reverse-copy N segments, and shrink by interpolation
  4345. case(3): // Fractal reverse-copy N segments, and shrink by addition
  4346. if((exit_status = fractal_copy_reverse_shorten(dz))<0)
  4347. return exit_status;
  4348. break;
  4349. case(4): //fall thro // Swap two halves of segment
  4350. case(5): // Reverse second half of segment
  4351. if((exit_status = fractal_by_halves(dz))<0)
  4352. return exit_status;
  4353. break;
  4354. case(6): //fall thro // Interleave two halves of segment
  4355. case(7): //fall thro // Reverse second half of segment, then interleave
  4356. case(8): // Reverse second half of segment, retaining original speed
  4357. if((exit_status = fractal_by_interleaving(dz))<0)
  4358. return exit_status;
  4359. break;
  4360. } // Ensure ALL sound converted to wav by PVOC synth
  4361. return FINISHED;
  4362. }
  4363. /**************************** FRACTAL_COPY_AND_SHRINK *****************************
  4364. *
  4365. * |--->--->--->--->| to |--->--->--->--->|--->--->--->--->| to |->->->->->->->->|
  4366. *
  4367. * |->->->->->->->->| to |->->->->->->->->|->->->->->->->->| to |>>>>>>>>>>>>>>>>|
  4368. */
  4369. // MODE 0
  4370. int fractal_copy_and_shrink(dataptr dz)
  4371. {
  4372. int exit_status;
  4373. int n = 0, buf2pos;
  4374. char outfilename[2000];
  4375. float *buf = dz->flbufptr[0];
  4376. for(n = 0;n < dz->iparam[FRACDEPTH]; n++) { // For every cut-stage : loop-n
  4377. if(dz->vflag[0]) {
  4378. dz->process_type = BIG_ANALFILE;
  4379. dz->outfiletype = ANALFILE_OUT;
  4380. if((exit_status = create_new_outfile(n,outfilename,dz))<0)
  4381. return exit_status;
  4382. }
  4383. buf2pos = 0; // Copy from AFTER window 0 to itemcnt
  4384. if((exit_status = frac_copy(&buf2pos,1,dz->itemcnt,dz))<0)
  4385. return exit_status;
  4386. if((exit_status = frac_copy(&buf2pos,1,dz->itemcnt,dz))<0)
  4387. return exit_status;
  4388. if((exit_status = frac_interp_shrink(dz)) < 0)
  4389. return exit_status;
  4390. if(dz->vflag[0]) {
  4391. if((exit_status = write_samps(buf,dz->itemcnt * dz->wanted,dz))<0)
  4392. return(exit_status);
  4393. if((exit_status = headwrite(dz->ofd,dz))<0) {
  4394. free(outfilename);
  4395. return(exit_status);
  4396. }
  4397. if(sndcloseEx(dz->ofd) < 0) {
  4398. fprintf(stdout,"WARNING: Can't close output soundfile %s\n",outfilename);
  4399. fflush(stdout);
  4400. }
  4401. dz->ofd = -1;
  4402. dz->process_type = OTHER_PROCESS; /* restore true status */
  4403. dz->outfiletype = NO_OUTPUTFILE; /* restore true status */
  4404. }
  4405. } // Include window zero in output-write
  4406. if(!dz->vflag[0]) {
  4407. if((exit_status = write_samps(buf,dz->itemcnt * dz->wanted,dz))<0)
  4408. return(exit_status);
  4409. }
  4410. return FINISHED;
  4411. }
  4412. /**************************** FRACTAL_REVERSE_COPY_AND_SHRINK *****************************
  4413. *
  4414. * |--->--->--->--->| to |--->--->--->--->|<---<---<---<---| to |->->->--<-<-<-<-|
  4415. *
  4416. * |->->->-><-<-<-<-| to |->->->-><-<-<-<-|<-<-<-<-->->->->| to |<<<<<<<<>>>>>>>>|
  4417. */
  4418. int fractal_reverse_copy_and_shrink(dataptr dz)
  4419. {
  4420. int exit_status;
  4421. int n = 0, buf2pos;
  4422. char outfilename[2000];
  4423. float *buf = dz->flbufptr[0];
  4424. for(n = 0;n < dz->iparam[FRACDEPTH]; n++) { // For every cut-stage : loop-n
  4425. if(dz->vflag[0]) {
  4426. dz->process_type = BIG_ANALFILE;
  4427. dz->outfiletype = ANALFILE_OUT;
  4428. if((exit_status = create_new_outfile(n,outfilename,dz))<0)
  4429. return exit_status;
  4430. }
  4431. buf2pos = 0; // Copy from AFTER window 0 to itemcnt
  4432. if((exit_status = frac_copy(&buf2pos,1,dz->itemcnt,dz))<0)
  4433. return exit_status;
  4434. if((exit_status = frac_reverse_copy(&buf2pos,1,dz->itemcnt,dz))<0)
  4435. return exit_status;
  4436. if((exit_status = frac_interp_shrink(dz)) < 0)
  4437. return exit_status;
  4438. if(dz->vflag[0]) {
  4439. if((exit_status = write_samps(buf,dz->itemcnt * dz->wanted,dz))<0)
  4440. return(exit_status);
  4441. if((exit_status = headwrite(dz->ofd,dz))<0) {
  4442. free(outfilename);
  4443. return(exit_status);
  4444. }
  4445. if(sndcloseEx(dz->ofd) < 0) {
  4446. fprintf(stdout,"WARNING: Can't close output soundfile %s\n",outfilename);
  4447. fflush(stdout);
  4448. }
  4449. dz->ofd = -1;
  4450. dz->process_type = OTHER_PROCESS; /* restore true status */
  4451. dz->outfiletype = NO_OUTPUTFILE; /* restore true status */
  4452. }
  4453. } // Include window zero in output-write
  4454. if(!dz->vflag[0]) {
  4455. if((exit_status = write_samps(buf,dz->itemcnt * dz->wanted,dz))<0)
  4456. return(exit_status);
  4457. }
  4458. return FINISHED;
  4459. }
  4460. /**************************** FRACTAL_COPY_REVERSE_SHORTEN *****************************
  4461. *
  4462. * SHRINK
  4463. *
  4464. * |-------------->| to |--------------->|<---------------| to |------->|<-------|
  4465. *
  4466. * |---A----|----B---| to |---A--->|<---A---|---B--->|<---B---| |-a->|<-a-|-b->|<-b-|
  4467. *
  4468. * |-a->|<-a-|-b->|<-b-| to |-a->|<-a-|<-a-|-a->||-b->|<-b-|<-b-|-b->| to |a>|<a|<a|a>|b>|<b|<b|b>|
  4469. *
  4470. * ADD
  4471. * |<---------------|
  4472. * |--------------->| to |--------------->|<---------------| to |--------------->|
  4473. *
  4474. * |---a1-->--a2--->|
  4475. * |<---a2--<--a1---| |<---a2--<---a1--|---a1-->--a2--->| |<--a2--<--a1----|
  4476. * |----a1-->--a2-->| to |---a1--->--a2-->|---a2-->--a1--->| to |---a2-->--a1--->|
  4477. * |---a1-->--a2--->|
  4478. */
  4479. int fractal_copy_reverse_shorten(dataptr dz)
  4480. {
  4481. int exit_status;
  4482. char outfilename[2000];
  4483. int grpcnt, cutcnt, startwin, endwin, n, j, buf2pos;
  4484. float *buf = dz->flbufptr[0];
  4485. grpcnt = dz->copycnt; // Start off repatterning all existing segments
  4486. cutcnt = 1;
  4487. for(n = 0;n < dz->iparam[FRACDEPTH]; n++) { // For every cut-stage : loop-n
  4488. if(dz->vflag[0]) {
  4489. dz->process_type = BIG_ANALFILE;
  4490. dz->outfiletype = ANALFILE_OUT;
  4491. if((exit_status = create_new_outfile(n,outfilename,dz))<0)
  4492. return exit_status;
  4493. }
  4494. startwin = 0; // Specify start and end windows of first-cut of cutcnt repatternings
  4495. endwin = grpcnt;
  4496. buf2pos = 0; // Reset pointer in 2nd window to 0;
  4497. for(j = 0; j < cutcnt;j ++) { // For the number of cuts to be made at this stage : loop-j
  4498. // Copy windows to 2nd buffer abcd
  4499. if((exit_status = frac_copy(&buf2pos,startwin,endwin,dz))<0)
  4500. return exit_status;
  4501. if((exit_status = frac_reverse_copy(&buf2pos,startwin,endwin,dz))<0)
  4502. return exit_status;
  4503. startwin += grpcnt;
  4504. endwin += grpcnt; // Advance start and end of cut in j-loop
  4505. }
  4506. switch (dz->mode) {
  4507. case(2):
  4508. if((exit_status = frac_interp_shrink(dz)) < 0)
  4509. return exit_status;
  4510. break;
  4511. case(3):
  4512. if((exit_status = frac_add_shrink(dz)) < 0)
  4513. return exit_status;
  4514. break;
  4515. }
  4516. if(dz->vflag[0]) {
  4517. if((exit_status = write_samps(buf,dz->itemcnt * dz->wanted,dz))<0)
  4518. return(exit_status);
  4519. if((exit_status = headwrite(dz->ofd,dz))<0) {
  4520. free(outfilename);
  4521. return(exit_status);
  4522. }
  4523. if(sndcloseEx(dz->ofd) < 0) {
  4524. fprintf(stdout,"WARNING: Can't close output soundfile %s\n",outfilename);
  4525. fflush(stdout);
  4526. }
  4527. dz->ofd = -1;
  4528. dz->process_type = OTHER_PROCESS; /* restore true status */
  4529. dz->outfiletype = NO_OUTPUTFILE; /* restore true status */
  4530. }
  4531. grpcnt /= 2; // Gpsize to Cut gets smaller (by 1/2)
  4532. cutcnt *= 2; // So The number of cuts goes up by 2
  4533. }
  4534. if(!dz->vflag[0]) {
  4535. if((exit_status = write_samps(buf,dz->itemcnt * dz->wanted,dz))<0)
  4536. return(exit_status);
  4537. }
  4538. return FINISHED;
  4539. }
  4540. /**************************** FRAC_COPY *****************************/
  4541. // COPY WINDOWS
  4542. int frac_copy(int *buf2pos,int startwin,int endwin,dataptr dz)
  4543. {
  4544. int n, sttsamp;
  4545. float *buf = dz->flbufptr[0], *buf2 = dz->flbufptr[1];
  4546. for(n = startwin; n < endwin; n++) {
  4547. sttsamp = n * dz->wanted;
  4548. memcpy((char *)&(buf2[*buf2pos]),(char *)&(buf[sttsamp]),dz->wanted * sizeof(float));
  4549. *buf2pos += dz->wanted;
  4550. }
  4551. return FINISHED;
  4552. }
  4553. /**************************** FRAC_REVERSE_COPY *****************************/
  4554. // COPY WINDOWS IN REVERSE ORDER
  4555. int frac_reverse_copy(int *buf2pos,int startwin,int endwin,dataptr dz)
  4556. {
  4557. int n, sttsamp;
  4558. float *buf = dz->flbufptr[0], *buf2 = dz->flbufptr[1];
  4559. for(n = endwin-1; n > startwin; n--) {
  4560. sttsamp = n * dz->wanted;
  4561. memcpy((char *)&(buf2[*buf2pos]),(char *)&(buf[sttsamp]),dz->wanted * sizeof(float));
  4562. *buf2pos += dz->wanted;
  4563. }
  4564. return FINISHED;
  4565. }
  4566. /**************************** FRAC_INTERP_SHRINK *****************************
  4567. *
  4568. * TIME-SHRINK TWO WINDOWS INTO ONE BY INTERPOLATING
  4569. *
  4570. * Buf Buf2
  4571. * size itemcnt size copycnt size copycnt
  4572. * |0<-------------->|<-------------->|<-------------->|
  4573. * = copycnt+1 | /
  4574. * | /
  4575. * Buf | / Interpolate
  4576. * size itemcnt |/
  4577. * |0<-------------->|<-------------->|
  4578. * = copycnt+1 size copycnt
  4579. *
  4580. *
  4581. * Buf Buf2
  4582. * size itemcnt size copycnt
  4583. * |0<-------------->|<-------------->|
  4584. * ^ |______________|
  4585. * | |
  4586. * |________________|
  4587. * Copy
  4588. *
  4589. */
  4590. int frac_interp_shrink(dataptr dz)
  4591. {
  4592. int copyto = 0, copyfrom = 0, n, m;
  4593. float *buf = dz->flbufptr[0], *buf2 = dz->flbufptr[1];
  4594. for(n = 1,m = 0; n < dz->itemcnt; n++,m+=2) { // Ignore window 0 -- and window 1, which retains value
  4595. copyto = n * dz->wanted;
  4596. copyfrom = m * dz->wanted;
  4597. memcpy((char *)&(buf[copyto]),(char *)&(buf2[copyfrom]),dz->wanted * sizeof(float));
  4598. }
  4599. memset((char *)buf2,0,dz->copycnt * 2 * dz->wanted * sizeof(float)); //SAFETY
  4600. return FINISHED;
  4601. }
  4602. /**************************** FRAC_ADD_SHRINK *****************************
  4603. *
  4604. * TIME-SHRINK TWO WINDOWS INTO ONE BY AVERAGING THEM
  4605. *
  4606. * Buf Buf2
  4607. * size itemcnt size copycnt size copycnt
  4608. * |0<-------------->|<-------------->|<-------------->|
  4609. * = copycnt+1 | /
  4610. * | /
  4611. * Buf | / Average
  4612. * size itemcnt |/
  4613. * |0<-------------->|<-------------->|
  4614. * = copycnt+1 size copycnt
  4615. *
  4616. *
  4617. * Buf Buf2
  4618. * size itemcnt size copycnt
  4619. * |0<-------------->|<-------------->|
  4620. * ^ |______________|
  4621. * | |
  4622. * |________________|
  4623. * Copy
  4624. *
  4625. */
  4626. int frac_add_shrink(dataptr dz)
  4627. {
  4628. int winfrom2, winto2, winto1, k, n, m, vc; // Ignore window 1 IN FIRST buffer
  4629. float *buf = dz->flbufptr[0], *buf2 = dz->flbufptr[1];
  4630. double val; // Add the 2 halves of the 2nd (double-length) buffer
  4631. for(k = 1,n = 0,m = dz->copycnt; n < dz->copycnt; k++,n++,m++) {
  4632. winfrom2 = m * dz->wanted; // Into the first buffer, ignoring window 1
  4633. winto2 = n * dz->wanted;
  4634. winto1 = k * dz->wanted; // Ignore window 1 IN FIRST buffer
  4635. for(vc = 0;vc < dz->wanted;vc++) {
  4636. val = (buf2[winto2 + vc] + buf2[winfrom2 + vc])/2.0; // Add the 2 halves of the 2nd (double-length) buffer
  4637. buf[winto1 + vc] = (float)val; // And place result in first buffer
  4638. }
  4639. }
  4640. memset((char *)buf2,0,dz->copycnt * 2 * dz->wanted * sizeof(float)); //SAFETY
  4641. return FINISHED;
  4642. }
  4643. /**************************** CREATE_NEW_OUTFILE *****************************/
  4644. int create_new_outfile(int n,char *outfilename,dataptr dz)
  4645. {
  4646. int exit_status;
  4647. char prefix_units[] = "_00";
  4648. char prefix_tens[] = "_0";
  4649. char prefix_hundreds[] = "_";
  4650. strcpy(outfilename,dz->wordstor[0]);
  4651. if(!sloom) {
  4652. if(n<10)
  4653. insert_new_chars_at_filename_end(outfilename,prefix_units);
  4654. else if(n<100)
  4655. insert_new_chars_at_filename_end(outfilename,prefix_tens);
  4656. else if(n<1000)
  4657. insert_new_chars_at_filename_end(outfilename,prefix_hundreds);
  4658. else {
  4659. sprintf(errstr,"Too many duplicates.\n");
  4660. return(PROGRAM_ERROR);
  4661. }
  4662. insert_new_number_at_filename_end(outfilename,n,0);
  4663. } else {
  4664. insert_new_number_at_filename_end(outfilename,n,1);
  4665. }
  4666. if((exit_status = create_sized_outfile(outfilename,dz))<0) {
  4667. if(!sloom) {
  4668. sprintf(errstr, "Soundfile %s already exists: Made %d outputs only.\n",outfilename,n);
  4669. dz->ofd = -1;
  4670. return(GOAL_FAILED);
  4671. } else {
  4672. dz->ofd = -1;
  4673. sprintf(errstr, "Failed to create outfile number %d\n",n+1);
  4674. return(SYSTEM_ERROR);
  4675. }
  4676. }
  4677. return FINISHED;
  4678. }
  4679. /**************************** FRACTAL_BY_HALVES *****************************/
  4680. int fractal_by_halves(dataptr dz)
  4681. {
  4682. int exit_status;
  4683. char outfilename[2000];
  4684. int grpcnt, cutcnt, startwin, endwin, n, j, buf2pos;
  4685. float *buf2 = dz->flbufptr[1];
  4686. grpcnt = dz->copycnt; // Start off repatterning all existing segments
  4687. cutcnt = 1;
  4688. for(n = 0;n < dz->iparam[FRACDEPTH]; n++) { // For every cut-stage : loop-n
  4689. if(dz->vflag[0]) {
  4690. dz->process_type = BIG_ANALFILE;
  4691. dz->outfiletype = ANALFILE_OUT;
  4692. if((exit_status = create_new_outfile(n,outfilename,dz))<0)
  4693. return exit_status;
  4694. }
  4695. startwin = 0; // Specify start and end windows of first-cut of cutcnt repatternings
  4696. endwin = grpcnt;
  4697. buf2pos = 0; // Reset pointer in 2nd window to 0;
  4698. for(j = 0; j < cutcnt;j ++) { // For the number of cuts to be made at this stage : loop-j
  4699. // Copy windows to 2nd buffer abcd
  4700. switch(dz->mode) {
  4701. case(4):
  4702. if((exit_status = frac_swap(&buf2pos,startwin,endwin,dz))<0)
  4703. return exit_status;
  4704. break;
  4705. case(5):
  4706. if((exit_status = frac_reverse_second_half(&buf2pos,startwin,endwin,dz))<0)
  4707. return exit_status;
  4708. break;
  4709. }
  4710. startwin += grpcnt;
  4711. endwin += grpcnt; // Advance start and end of cut in j-loop
  4712. }
  4713. if(dz->vflag[0]) {
  4714. if((exit_status = write_samps(buf2,dz->itemcnt * dz->wanted,dz))<0)
  4715. return(exit_status);
  4716. if((exit_status = headwrite(dz->ofd,dz))<0) {
  4717. free(outfilename);
  4718. return(exit_status);
  4719. }
  4720. if(sndcloseEx(dz->ofd) < 0) {
  4721. fprintf(stdout,"WARNING: Can't close output soundfile %s\n",outfilename);
  4722. fflush(stdout);
  4723. }
  4724. dz->ofd = -1;
  4725. dz->process_type = OTHER_PROCESS; /* restore true status */
  4726. dz->outfiletype = NO_OUTPUTFILE; /* restore true status */
  4727. }
  4728. grpcnt /= 2; // Gpsize to Cut gets smaller (by 1/2)
  4729. cutcnt *= 2; // So The number of cuts goes up by 2
  4730. }
  4731. if(!dz->vflag[0]) {
  4732. if((exit_status = write_samps(buf2,dz->itemcnt * dz->wanted,dz))<0)
  4733. return(exit_status);
  4734. }
  4735. return FINISHED;
  4736. }
  4737. /**************************** FRAC_SWAP *****************************
  4738. *
  4739. * SWAP TWO HALVES OF SEGMENT
  4740. *
  4741. * |abcdefghIJKLMNOP| -> |IJKLMNOPabcdefgh| swap 8s
  4742. * |abcdefghIJKLMNOP| -> |efghabcdMNOPIJKL| swap 4s
  4743. * |abcdefghIJKLMNOP| -> |cdabghefKLIJOPMN| swap 2s
  4744. * |abcdefghIJKLMNOP| -> |badcfehgJILKNMPO| swap 1s
  4745. */
  4746. int frac_swap(int *buf2pos,int startwin,int endwin,dataptr dz)
  4747. {
  4748. int n, m, sttsamp, goalsamp, bufinc;
  4749. float *buf = dz->flbufptr[0] + dz->wanted, *buf2 = dz->flbufptr[1];
  4750. int halfswaplen = (endwin - startwin)/2;
  4751. int halfbuspos = startwin + halfswaplen;
  4752. bufinc = 0;
  4753. for(n = startwin + halfswaplen, m = startwin; m < halfbuspos; n++,m++) {
  4754. sttsamp = n * dz->wanted;
  4755. goalsamp = m * dz->wanted;
  4756. memcpy((char *)&(buf2[goalsamp]),(char *)&(buf[sttsamp]),dz->wanted * sizeof(float));
  4757. bufinc += dz->wanted;
  4758. }
  4759. for(n = startwin, m = startwin + halfswaplen; n < halfbuspos; n++,m++) {
  4760. sttsamp = n * dz->wanted;
  4761. goalsamp = m * dz->wanted;
  4762. memcpy((char *)&(buf2[goalsamp]),(char *)&(buf[sttsamp]),dz->wanted * sizeof(float));
  4763. bufinc += dz->wanted;
  4764. }
  4765. *buf2pos += bufinc;
  4766. return FINISHED;
  4767. }
  4768. /**************************** FRAC_REVERSE_SECOND_HALF *****************************
  4769. *
  4770. * REVERSE 2nd HALF OF SEGMENT
  4771. *
  4772. * |abcdefghIJKLMNOP| -> |abcdefghPONMLKJI| reverse-2ndhalf 8s
  4773. * |abcdefghIJKLMNOP| -> |abcdhgfeIJKLPONM| reverse-2ndhalf 4s
  4774. * |abcdefghIJKLMNOP| -> |abdcefhgIJLKMNPO| reverse-2ndhalf 2s
  4775. * |abcdefghIJKLMNOP| -> |badcfehgJILKNMPO| reverse-2ndhalf 1s
  4776. *
  4777. */
  4778. int frac_reverse_second_half(int *buf2pos,int startwin,int endwin,dataptr dz)
  4779. {
  4780. int n, m, sttsamp, goalsamp, bufinc;
  4781. float *buf = dz->flbufptr[0] + dz->wanted, *buf2 = dz->flbufptr[1];
  4782. int halfswaplen = (endwin - startwin)/2;
  4783. int halfbuspos = startwin + halfswaplen;
  4784. bufinc = 0;
  4785. for(n = startwin, m = startwin; m < halfbuspos; m++,n++) { // COPY FIRST HALF
  4786. sttsamp = n * dz->wanted;
  4787. goalsamp = m * dz->wanted;
  4788. memcpy((char *)&(buf2[goalsamp]),(char *)&(buf[sttsamp]),dz->wanted * sizeof(float));
  4789. bufinc += dz->wanted;
  4790. }
  4791. startwin += halfswaplen;
  4792. endwin += halfswaplen;
  4793. for(n = startwin, m = endwin - 1; m >= halfbuspos; m--,n++) { // REVERSE COPY SECOND HALF
  4794. sttsamp = n * dz->wanted;
  4795. goalsamp = m * dz->wanted;
  4796. memcpy((char *)&(buf2[goalsamp]),(char *)&(buf[sttsamp]),dz->wanted * sizeof(float));
  4797. bufinc += dz->wanted;
  4798. }
  4799. *buf2pos += bufinc;
  4800. return FINISHED;
  4801. }
  4802. /**************************** FRAC_INTERLEAVE *****************************
  4803. *
  4804. * INTERLEAVE TWO HALVES OF SEGMENT
  4805. *
  4806. * |abcdefghIJKLMNOP| -> |abcdefghIJKLMNOP| intlv 8s x
  4807. * |abcdefghIJKLMNOP| -> |abcdIJKLefghMNOP| intlv 4s
  4808. * |abcdefghIJKLMNOP| -> |abIJcdKLefMNghOP| intlv 2s
  4809. * |abcdefghIJKLMNOP| -> |aIbJcKdLeMfNgOhP| intlv 1s
  4810. */
  4811. int frac_interleave(int gpcnt,dataptr dz)
  4812. {
  4813. int cnt_in_1sthalf, cnt_in_2ndhalf, k, z, sttsamp, goalsamp;
  4814. float *buf = dz->flbufptr[0] + dz->wanted, *buf2 = dz->flbufptr[1]; // Ignore zero-window in input
  4815. int itlvlen = dz->copycnt;
  4816. int halfitlvlen = itlvlen/2;
  4817. int qatritlvlen = gpcnt/4;
  4818. k = 0;
  4819. cnt_in_1sthalf = 0;
  4820. cnt_in_2ndhalf = halfitlvlen;
  4821. for(z = 0; z < qatritlvlen; z++, cnt_in_1sthalf++) {
  4822. sttsamp = cnt_in_1sthalf * dz->wanted; // cnt_in_1sthalf starts at 0 gets to 1/4 way
  4823. goalsamp = k * dz->wanted;
  4824. memcpy((char *)&(buf2[goalsamp]),(char *)&(buf[sttsamp]),dz->wanted * sizeof(float));
  4825. k++;
  4826. }
  4827. for(z = 0; z < qatritlvlen; z++, cnt_in_2ndhalf++) {
  4828. sttsamp = cnt_in_2ndhalf * dz->wanted; // cnt_in_2ndhalf starts at 1/2 gets to 3/4 way
  4829. goalsamp = k * dz->wanted;
  4830. memcpy((char *)&(buf2[goalsamp]),(char *)&(buf[sttsamp]),dz->wanted * sizeof(float));
  4831. k++;
  4832. }
  4833. while(k < dz->copycnt) {
  4834. for(z = 0; z < qatritlvlen; z++, cnt_in_1sthalf++) { // cnt_in_1sthalf starts at 1/4 way gets to 1/2 way
  4835. sttsamp = cnt_in_1sthalf * dz->wanted;
  4836. goalsamp = k * dz->wanted;
  4837. memcpy((char *)&(buf2[goalsamp]),(char *)&(buf[sttsamp]),dz->wanted * sizeof(float));
  4838. k++;
  4839. }
  4840. for(z = 0; z < qatritlvlen; z++, cnt_in_2ndhalf++) { // cnt_in_2ndhalf starts at 3/4 gets to end
  4841. sttsamp = cnt_in_2ndhalf * dz->wanted;
  4842. goalsamp = k * dz->wanted;
  4843. memcpy((char *)&(buf2[goalsamp]),(char *)&(buf[sttsamp]),dz->wanted * sizeof(float));
  4844. k++;
  4845. }
  4846. }
  4847. return FINISHED;
  4848. }
  4849. /**************************** FRAC_INTERLEAVE_REVERSE *****************************
  4850. *
  4851. * INTERLEAVE/REVERSE TWO HALVES OF SEGMENT
  4852. *
  4853. * |abcdefghIJKLMNOP| -> |abcdefghPONMLKJI| swap 8s
  4854. * |abcdefghIJKLMNOP| -> |abcdPONMefghLKJI| swap 4s
  4855. * |abcdefghIJKLMNOP| -> |abPOcdNMefLKghJI| swap 2s
  4856. * |abcdefghIJKLMNOP| -> |aPbOcNdMeLfKgJhI| swap 1s
  4857. */
  4858. int frac_interleave_reverse(int gpcnt,dataptr dz)
  4859. {
  4860. int cnt_in_1sthalf, cnt_in_2ndhalf, k, z, sttsamp, goalsamp;
  4861. float *buf = dz->flbufptr[0] + dz->wanted, *buf2 = dz->flbufptr[1]; // Ignore zero-window in input
  4862. int itlvlen = dz->copycnt;
  4863. int halfitlvlen = itlvlen/2;
  4864. int qatritlvlen = gpcnt/4;
  4865. k = 0;
  4866. cnt_in_1sthalf = 0;
  4867. cnt_in_2ndhalf = halfitlvlen + qatritlvlen - 1; // Go to END of first segment in 2nd half
  4868. for(z = 0; z < qatritlvlen; z++, cnt_in_1sthalf++) {
  4869. sttsamp = cnt_in_1sthalf * dz->wanted; // cnt_in_1sthalf starts at 0 gets to 1/4 way
  4870. goalsamp = k * dz->wanted;
  4871. memcpy((char *)&(buf2[goalsamp]),(char *)&(buf[sttsamp]),dz->wanted * sizeof(float));
  4872. k++;
  4873. }
  4874. for(z = 0; z < qatritlvlen; z++, cnt_in_2ndhalf--) {
  4875. sttsamp = cnt_in_2ndhalf * dz->wanted; // cnt_in_2ndhalf starts at 1/2 gets to 3/4 way
  4876. goalsamp = k * dz->wanted;
  4877. memcpy((char *)&(buf2[goalsamp]),(char *)&(buf[sttsamp]),dz->wanted * sizeof(float));
  4878. k++;
  4879. }
  4880. while(k < dz->copycnt) {
  4881. for(z = 0; z < qatritlvlen; z++, cnt_in_1sthalf++) { // cnt_in_1sthalf starts at 1/4 way gets to 1/2 way
  4882. sttsamp = cnt_in_1sthalf * dz->wanted;
  4883. goalsamp = k * dz->wanted;
  4884. memcpy((char *)&(buf2[goalsamp]),(char *)&(buf[sttsamp]),dz->wanted * sizeof(float));
  4885. k++;
  4886. }
  4887. cnt_in_2ndhalf += (qatritlvlen * 2) - 1; // Go from start of current segment, to END of next
  4888. for(z = 0; z < qatritlvlen; z++, cnt_in_2ndhalf--) {
  4889. sttsamp = cnt_in_2ndhalf * dz->wanted; // cnt_in_2ndhalf starts at 1/2 gets to 3/4 way
  4890. goalsamp = k * dz->wanted;
  4891. memcpy((char *)&(buf2[goalsamp]),(char *)&(buf[sttsamp]),dz->wanted * sizeof(float));
  4892. k++;
  4893. }
  4894. }
  4895. return FINISHED;
  4896. }
  4897. /**************************** FRAC_INTERLEAVE_CYCLE *****************************
  4898. *
  4899. * INTERLEAVE TWO HALVES OF SEGMENT, BUT PROGRESS AT ORIGINAL SPEED
  4900. *
  4901. * |abcdefghIJKLMNOP| -> |abcdefghIJKLMNOP| intlv 8s x
  4902. * |abcdefghIJKLMNOP| -> |abcdMNOPIJKLefgh| intlv 4s
  4903. * |abcdefghIJKLMNOP| -> |abKLefOPIJcdMNgh| intlv 2s
  4904. * |abcdefghIJKLMNOP| -> |aJcLeNgPIbKdMfOh| intlv 1s
  4905. */
  4906. int frac_interleave_cycle(int gpcnt,dataptr dz)
  4907. {
  4908. int cnt_in_1sthalf, cnt_in_2ndhalf, k, z, sttsamp, goalsamp;
  4909. float *buf = dz->flbufptr[0] + dz->wanted, *buf2 = dz->flbufptr[1]; // Ignore zero-window in input
  4910. int itlvlen = dz->copycnt;
  4911. int halfitlvlen = itlvlen/2;
  4912. int qatritlvlen = gpcnt/4;
  4913. k = 0;
  4914. cnt_in_1sthalf = 0;
  4915. cnt_in_2ndhalf = halfitlvlen + 1;
  4916. if(qatritlvlen <= 0) {
  4917. sprintf(errstr,"INCORRECT DIVISION OF THE SPECTRUM\n");
  4918. return PROGRAM_ERROR;
  4919. }
  4920. while(k < dz->copycnt) {
  4921. for(z = 0; z < qatritlvlen; z++, cnt_in_1sthalf++) {
  4922. sttsamp = cnt_in_1sthalf * dz->wanted; // cnt_in_1sthalf starts at 0
  4923. goalsamp = k * dz->wanted;
  4924. memcpy((char *)&(buf2[goalsamp]),(char *)&(buf[sttsamp]),dz->wanted * sizeof(float));
  4925. k++;
  4926. }
  4927. for(z = 0; z < qatritlvlen; z++, cnt_in_2ndhalf++) {
  4928. sttsamp = cnt_in_2ndhalf * dz->wanted; // cnt_in_2ndhalf starts at 1
  4929. goalsamp = k * dz->wanted;
  4930. memcpy((char *)&(buf2[goalsamp]),(char *)&(buf[sttsamp]),dz->wanted * sizeof(float));
  4931. k++;
  4932. }
  4933. cnt_in_1sthalf += qatritlvlen; // Leap over next window, in both halves
  4934. cnt_in_2ndhalf += qatritlvlen;
  4935. if(cnt_in_2ndhalf >= dz->copycnt)
  4936. cnt_in_2ndhalf -= dz->copycnt;
  4937. }
  4938. return FINISHED;
  4939. }
  4940. /**************************** FRACTAL_BY_INTERLEAVING *****************************/
  4941. int fractal_by_interleaving(dataptr dz)
  4942. {
  4943. int exit_status;
  4944. char outfilename[2000];
  4945. int grpcnt, n;
  4946. float *buf = dz->flbufptr[0], *buf2 = dz->flbufptr[1];
  4947. grpcnt = dz->copycnt; // Start off repatterning all existing segments
  4948. if(dz->vflag[0]) {
  4949. for(n = 0;n < dz->iparam[FRACDEPTH]; n++) { // For every cut-stage : loop-n
  4950. dz->process_type = BIG_ANALFILE;
  4951. dz->outfiletype = ANALFILE_OUT;
  4952. if((exit_status = create_new_outfile(n,outfilename,dz))<0)
  4953. return exit_status;
  4954. switch(dz->mode) {
  4955. case(6):
  4956. if((exit_status = frac_interleave(grpcnt,dz))<0)
  4957. return exit_status;
  4958. break;
  4959. case(7):
  4960. if((exit_status = frac_interleave_reverse(grpcnt,dz))<0)
  4961. return exit_status;
  4962. break;
  4963. case(8):
  4964. if((exit_status = frac_interleave_cycle(grpcnt,dz))<0)
  4965. return exit_status;
  4966. break;
  4967. }
  4968. if((exit_status = write_samps(buf,dz->wanted,dz))<0) // Write initial zero-buffer
  4969. return(exit_status);
  4970. if((exit_status = write_samps(buf2,dz->itemcnt * dz->wanted,dz))<0)
  4971. return(exit_status);
  4972. if((exit_status = headwrite(dz->ofd,dz))<0) {
  4973. free(outfilename);
  4974. return(exit_status);
  4975. }
  4976. if(sndcloseEx(dz->ofd) < 0) {
  4977. fprintf(stdout,"WARNING: Can't close output soundfile %s\n",outfilename);
  4978. fflush(stdout);
  4979. }
  4980. dz->ofd = -1;
  4981. dz->process_type = OTHER_PROCESS; /* restore true status */
  4982. dz->outfiletype = NO_OUTPUTFILE; /* restore true status */
  4983. grpcnt /= 2; // Gpsize to Cut gets smaller (by 1/2)
  4984. }
  4985. } else {
  4986. for(n = 0;n < dz->iparam[FRACDEPTH]; n++) // For every cut-stage : loop-n
  4987. grpcnt /= 2; // Gpsize to Cut gets smaller (by 1/2)
  4988. switch(dz->mode) {
  4989. case(6):
  4990. if((exit_status = frac_interleave(grpcnt,dz))<0)
  4991. return exit_status;
  4992. break;
  4993. case(7):
  4994. if((exit_status = frac_interleave_reverse(grpcnt,dz))<0)
  4995. return exit_status;
  4996. break;
  4997. case(8):
  4998. if((exit_status = frac_interleave_cycle(grpcnt,dz))<0)
  4999. return exit_status;
  5000. break;
  5001. }
  5002. if((exit_status = write_samps(buf,dz->wanted,dz))<0) // Write initial zero-buffer
  5003. return(exit_status);
  5004. if((exit_status = write_samps(buf2,dz->itemcnt * dz->wanted,dz))<0)
  5005. return(exit_status);
  5006. }
  5007. return FINISHED;
  5008. }