grain1.c 154 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744
  1. /*
  2. * Copyright (c) 1983-2023 Trevor Wishart and Composers Desktop Project Ltd
  3. * http://www.trevorwishart.co.uk
  4. * http://www.composersdesktop.com
  5. *
  6. This file is part of the CDP System.
  7. The CDP System is free software; you can redistribute it
  8. and/or modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  11. The CDP System is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU Lesser General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public
  16. License aint 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. /* floatsam vesion */
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <memory.h>
  26. #include <structures.h>
  27. #include <tkglobals.h>
  28. #include <globcon.h>
  29. #include <processno.h>
  30. #include <modeno.h>
  31. #include <arrays.h>
  32. #include <grain.h>
  33. #include <cdpmain.h>
  34. #define maxtime scalefact
  35. #include <sfsys.h>
  36. #include <osbind.h>
  37. #include <grain.h>
  38. #ifndef HUGE
  39. #define HUGE 3.40282347e+38F
  40. #endif
  41. //#ifdef unix
  42. #define round(x) lround((x))
  43. //#endif
  44. static int copygrain_from_elsewhere(int len,int k,int *obufposition,dataptr dz);
  45. static int store_the_grain_time(int grainstart,int *graincnt,int crosbuf,double samptotime,int init,dataptr dz);
  46. static int retime_grain(int ibufpos,int thisgap,int grainstart,int origgap,int bufno,int *obufpos,
  47. int chans,int crosbuf,int *grainadjusted,int store_end,int is_first_grain,dataptr dz);
  48. static int keep_non_omitted_grains(int ibufpos,int bufno,int grainstart,int *graincnt,
  49. int *obufpos,int crosbuf,int chans,int is_first_grain,dataptr dz);
  50. static int do_the_reordered_grains(int ibufpos,int bufno,int grainstart,int *graincnt,
  51. int *obufpos,int crosbuf,int chans,int is_first_grain,int is_last_grain,dataptr dz);
  52. static int synchronise_the_grain(int ibufpos,int *graincnt,int bufno,int gapcnt,int *obufpos,
  53. int grainstart,int crosbuf,int chans,int *grainadjusted,int is_first_grain,dataptr dz);
  54. static int do_final_reorder_grains(int graincnt,int *obufpos,dataptr dz);
  55. //TW REVISED
  56. static int output_final_grain(int grainstart,int start_splice,int bufno,int splicestart_bufno,int is_first_grain,
  57. int *obufpos,int grainlen,int crosbuf,dataptr dz);
  58. static int do_rerhythm_grain(int ibufpos,int *graincnt,int bufno,int gapcnt,int *obufpos,int grainstart,
  59. int crosbuf,int chans,int *grainadjusted,int is_first_grain,dataptr dz);
  60. static void swap_array_adresses_and_lens_for_reordr(int n,int m,dataptr dz);
  61. static int copy_grain_to_buf(int ibufpos,int bufno,int grainstart,int crosbuf,int chans,int n,dataptr dz);
  62. //TW REVISED
  63. static int retime_pre_firstgrain_material
  64. (int new_grainstart,int *obufposition,int chans,int crosbuf,dataptr dz);
  65. static int output_grain_link(int thisgap,int abs_halfsplice,int *obufposition,dataptr dz);
  66. static int copy_start_of_grain(int grainstart,int start_splice,int bufno,int splicestart_bufno,
  67. int *obufpos,int crosbuf,dataptr dz);
  68. static int read_dn_halfsplice(int *obufposition,int len,dataptr dz);
  69. static int create_an_upsplice_from_pregrain_material(int obufpos,int chans,dataptr dz);
  70. static int duplicate_grain(int ibufpos,int bufno,int gapcnt,int *obufpos,int grainstart,
  71. int crosbuf,int chans,int *grainadjusted,int is_first_grain,dataptr dz);
  72. static int prepare_final_grain(int ibufpos,int *start_splice,int bufno,int *splicestart_bufno,
  73. int grainstart,int *grainlen,int crosbuf,int chans,dataptr dz);
  74. static int read_up_halfsplice(int *obufposition,int len,dataptr dz);
  75. static int store_up_halfsplice(int storeno,int start,int bufno,int chans,int splicelen,dataptr dz);
  76. static int store_dn_halfsplice(int start,int bufno,int chans,int splicelen,dataptr dz);
  77. //TW REVISED
  78. static int duplicate_last_grain(int ibufpos,int bufno,int *obufpos,int grainstart,
  79. int crosbuf,int chans,int is_first_grain,dataptr dz);
  80. static int store_upsplice_of_next_grain(int ibufpos,int bufno,int abs_halfsplice,int chans,dataptr dz);
  81. static int copy_last_grain_to_buf(int ibufpos,int bufno,int grainstart,int crosbuf,int chans,int n,dataptr dz);
  82. static int copy_up_halfsplice_to_grainstore(int len,int storeno,int storelen,int *storepos,dataptr dz);
  83. static int copy_dn_halfsplice_to_grainstore(int len,int storeno,int storelen,int storepos,dataptr dz);
  84. static int copy_midgrain_to_store(int mid_grainlen,int bufno,int storelen,int grainstart,
  85. int *storepos,int crosbuf,int storeno,dataptr dz);;
  86. static int put_grain_into_store(int is_last_grain,int ibufpos,int bufno,int grainstart,
  87. int crosbuf,int chans,int graincnt,dataptr dz);
  88. static int save_abs_sampletime_of_grain(int grainstart,int *graincnt,int crosbuf,dataptr dz);
  89. static int do_seek_and_read(int *seekbufs, int *seeksamps,int grainno,dataptr dz);
  90. static int test_buffer_overflows(float *obuf,int *obufpos,int *ibufpos,int n,int maxlen,int *crosbuf,dataptr dz);
  91. static int do_the_reversing_process(int graincnt,int *obufposition,int chans,dataptr dz);
  92. static int output_up_halfsplice(int *ibufpos,int *obufpos,int chans,int splicelen,int *crosbuf,dataptr dz);
  93. static int output_dn_halfsplice(int *ibufpos,int *obufpos,int chans,int splicelen,int *crosbuf,dataptr dz);
  94. static int copy_midgrain_to_output(int mid_grainlen,int *ibufpos,int *obufpos,int *crosbuf,int chans,dataptr dz);
  95. static int insert_EOF_sampletime_in_samptime_list(int graincnt,dataptr dz);
  96. static void adjust_for_last_grain(int *graincnt,int *grainpos,dataptr dz);
  97. static int clear_outbuf(dataptr dz);
  98. static int output_whole_grain(int n,int *obufpos,int *seeksamps,int *seekbufs,
  99. int halfsplice,int abs_splicelen,int chans,dataptr dz);
  100. static int adjust_firstgrain_upsplice(int *ibufpos,int *startsplice,int n,int chans);
  101. static int do_grain_repitching(int *actual_grainlen,int bufno,int grainstart,
  102. int new_grainlen,int orig_grainlen,int chans,int crosbuf,double pichratio,dataptr dz);
  103. static int test_for_bufcros(int *thishere,float **b,int bufno,int crosbuf,dataptr dz);
  104. static int save_nextgrain_upsplice_elsewhere(int ibufpos,int bufno,int abs_halfsplice,int halfsplice,
  105. int chans,dataptr dz);
  106. static int copygrain_from_grainbuf_to_outbuf(int *obufpos,int grainlen,dataptr dz);
  107. static int retrieve_upsplice_for_nextgrain(int abs_halfsplice,dataptr dz);
  108. static int save_origgrain_length_and_store_nextgrains_upsplice(int *orig_grainlen,int ibufpos,int bufno,
  109. int grainstart,int abs_halfsplice,int halfsplice,int crosbuf,int chans,int is_last_grain,dataptr dz);
  110. //TW REVISED
  111. static int create_repitched_and_retimed_grain(int bufno,int grainstart,int orig_grainlen,
  112. int *new_grainlen,double pichratio,double timeratio,int *obufpos,int *is_first_grain,
  113. int *grainadjusted,int abs_halfsplice,int chans,int crosbuf,dataptr dz);
  114. static int repitch_main_body_of_grain(int bufno,int grainstart,int new_grainlen,int orig_grainlen,
  115. double pichratio,int chans,int crosbuf,int halfsplice,int abs_halfsplice,dataptr dz);
  116. //TW REVISED
  117. static int retime_main_body_of_grain(int grainstart,int bufno,double pichratio,
  118. double timeratio,int chans,int crosbuf,int *grainadjusted,
  119. int orig_grainlen,int *new_grainlen,dataptr dz);
  120. static int repitching_process(int ibufpos,int bufno,int grainstart,int abs_halfsplice,int halfsplice,
  121. int *graincnt,int *obufpos,int *orig_grainlen,int *new_grainlen,int *grainadjusted,
  122. int *is_first_grain,int is_last_grain,int chans,int crosbuf,dataptr dz);
  123. static int repitching_and_retiming_process(int ibufpos,int bufno,int grainstart,int abs_halfsplice,
  124. int halfsplice,int *graincnt,int *obufpos,int *orig_grainlen,int *new_grainlen,
  125. int *grainadjusted,int *is_first_grain,int is_last_grain,int chans,int crosbuf,dataptr dz);
  126. static int do_in_situ_halfsplice_on_stored_grain(int bufpos,int chans,int splicelen,int grainstorelen,dataptr dz);
  127. static int locate_zero_crossings(int local_minima_cnt,dataptr dz);
  128. static int which_minimum_to_eliminate(int minsegstartpos,int *pos,int maxseg,int segcnt,int *eliminate_pos,dataptr dz);
  129. static int eliminate_excess_minima(int *local_minima_cnt,int *pos,dataptr dz);
  130. static int find_all_local_minima(int peakcnt,int *local_minima_cnt,dataptr dz);
  131. static int find_all_positive_peaks(int startsearch,int endsearch,int *peakcnt,dataptr dz);
  132. static int eliminate_spurious_minima(int *local_minima_cnt,int *minimum_element_len,dataptr dz);
  133. static void hhshuflup(int k,int setlen,int *perm);
  134. static void hhprefix(int m,int setlen,int *perm);
  135. static void hhinsert(int m,int t,int setlen,int *perm);
  136. static void do_repet_restricted_perm(int *arr, int *perm, int arrsiz, int allowed, int endval);
  137. static int rand_ints_with_restricted_repeats(int element_cnt,int max_elements_needed,int arrsiz,int fullperms,int **pattern,dataptr dz);
  138. static int extract_rrr_env_from_sndfile(int paramno,dataptr dz);
  139. static void get_rrrenv_of_buffer(int samps_to_process,int envwindow_sampsize,float **envptr,float *buffer);
  140. static float getmaxsampr(int startsamp, int sampcnt,float *buffer);
  141. static int do_envgrain_write(int startsearch,int endsearch,int *last_total_samps_read,int *obufpos,dataptr dz);
  142. static int do_envgrain_zerowrite(int startsearch,int endsearch,int *obufpos,dataptr dz);
  143. static int do_envgrain_addwrite(int startsearch,int endsearch,int *last_total_samps_read,int *obufpos,dataptr dz);
  144. static int do_envgrain_zerowrite_dblbuf(int startsearch,int endsearch,int *obufpos,dataptr dz);
  145. /************************** DO_THE_GRAIN **********************/
  146. int do_the_grain(int ibufpos,int *graincnt,int bufno,int gapcnt,int *obufpos,int grainstart,
  147. int crosbuf,int chans,int *grainadjusted,double samptotime,
  148. int *is_first_grain,dataptr dz)
  149. {
  150. int exit_status;
  151. int is_last_grain = FALSE;
  152. int newgapcnt, orig_grainlen, new_grainlen;
  153. int abs_splicelen = dz->iparam[GR_ABS_SPLICELEN];
  154. int abs_halfsplice = abs_splicelen/2; /* guaranteed to fall on stereo boundary */
  155. int halfsplice = dz->iparam[GR_SPLICELEN]/2;
  156. int store_end;
  157. static int init = 1;
  158. switch(dz->process) {
  159. case(GRAIN_COUNT):
  160. (*graincnt)++;
  161. break;
  162. case(GRAIN_GET):
  163. case(GRAIN_ALIGN):
  164. if((exit_status = store_the_grain_time(grainstart,graincnt,crosbuf,samptotime,init,dz))<0)
  165. return(exit_status);
  166. init = 0;
  167. break;
  168. case(GRAIN_REPITCH):
  169. if((exit_status = repitching_process(ibufpos,bufno,grainstart,abs_halfsplice,halfsplice,graincnt,
  170. obufpos,&orig_grainlen,&new_grainlen,grainadjusted,is_first_grain,is_last_grain,chans,crosbuf,dz))<0)
  171. return(exit_status);
  172. if((exit_status = retrieve_upsplice_for_nextgrain(abs_halfsplice,dz))<0)
  173. return(exit_status);
  174. break;
  175. case(GRAIN_REMOTIF):
  176. if((exit_status = repitching_and_retiming_process(ibufpos,bufno,grainstart,abs_halfsplice,halfsplice,graincnt,
  177. obufpos,&orig_grainlen,&new_grainlen,grainadjusted,is_first_grain,is_last_grain,chans,crosbuf,dz))<0)
  178. return(exit_status);
  179. if((exit_status = retrieve_upsplice_for_nextgrain(abs_halfsplice,dz))<0)
  180. return(exit_status);
  181. break;
  182. case(GRAIN_RERHYTHM):
  183. if((exit_status = do_rerhythm_grain
  184. (ibufpos,graincnt,bufno,gapcnt,obufpos,grainstart,crosbuf,chans,grainadjusted,*is_first_grain,dz))<0)
  185. return(exit_status);
  186. break;
  187. case(GRAIN_OMIT):
  188. if((exit_status = keep_non_omitted_grains
  189. (ibufpos,bufno,grainstart,graincnt,obufpos,crosbuf,chans,*is_first_grain,dz))<0)
  190. return(exit_status);
  191. break;
  192. case(GRAIN_REORDER):
  193. if((exit_status = do_the_reordered_grains
  194. (ibufpos,bufno,grainstart,graincnt,obufpos,crosbuf,chans,*is_first_grain,is_last_grain,dz))<0)
  195. return(exit_status);
  196. break;
  197. case(GRAIN_DUPLICATE):
  198. if((exit_status = duplicate_grain
  199. (ibufpos,bufno,gapcnt,obufpos,grainstart,crosbuf,chans,grainadjusted,*is_first_grain,dz))<0)
  200. return(exit_status);
  201. break;
  202. case(GRAIN_TIMEWARP):
  203. newgapcnt = round((double)(gapcnt/chans) * dz->param[GR_TSTRETCH]) * chans;
  204. store_end = TRUE;
  205. if((exit_status = retime_grain
  206. (ibufpos,newgapcnt,grainstart,gapcnt,bufno,obufpos,chans,crosbuf,grainadjusted,store_end,*is_first_grain,dz))<0)
  207. return(exit_status);
  208. break;
  209. case(GRAIN_REVERSE):
  210. if(*is_first_grain) {
  211. fprintf(stdout,"INFO: Searching for grains\n");
  212. fflush(stdout);
  213. }
  214. if((exit_status = save_abs_sampletime_of_grain(grainstart,graincnt,crosbuf,dz))<0)
  215. return(exit_status);
  216. break;
  217. case(GRAIN_POSITION):
  218. if((exit_status = synchronise_the_grain
  219. (ibufpos,graincnt,bufno,gapcnt,obufpos,grainstart,crosbuf,chans,grainadjusted,*is_first_grain,dz))<0)
  220. return(exit_status);
  221. if(exit_status!=CONTINUE)
  222. return(FINISHED);
  223. break;
  224. default:
  225. sprintf(errstr,"Unknown case in do_the_grain()\n");
  226. return(PROGRAM_ERROR);
  227. }
  228. *is_first_grain = FALSE;
  229. return(CONTINUE);
  230. }
  231. /************************** STORE_THE_GRAIN_TIME **********************/
  232. int store_the_grain_time(int grainstart,int *graincnt,int crosbuf,double samptotime,int init,dataptr dz)
  233. {
  234. int previous_total_ssampsread = dz->total_samps_read - dz->ssampsread;
  235. int sampcnt = grainstart + previous_total_ssampsread;
  236. if(init) {
  237. if(*graincnt == 0) {
  238. sprintf(errstr,"No grains found.\n");
  239. return(GOAL_FAILED);
  240. }
  241. if((dz->parray[GR_SYNCTIME] = (double *)malloc(*graincnt * sizeof(double)))==NULL) {
  242. sprintf(errstr,"INSUFFICIENT MEMORY to store sync times.\n");
  243. return(MEMORY_ERROR);
  244. }
  245. dz->iparam[GR_SYNCCNT] = *graincnt;
  246. *graincnt = 0;
  247. } else if(dz->parray[GR_SYNCTIME] == NULL) {
  248. sprintf(errstr,"No grains found.\n");
  249. return(GOAL_FAILED);
  250. }
  251. if(crosbuf)
  252. sampcnt -= dz->buflen;
  253. dz->parray[GR_SYNCTIME][(*graincnt)++] = (double)sampcnt * samptotime;
  254. if(*graincnt > dz->iparam[GR_SYNCCNT]) {
  255. sprintf(errstr,"Error in memory asignment for storing grain times.\n");
  256. return(PROGRAM_ERROR);
  257. }
  258. return(FINISHED);
  259. }
  260. /************************* KEEP_NON_OMITTED_GRAINS *************************/
  261. int keep_non_omitted_grains
  262. (int ibufpos,int bufno,int grainstart,int *graincnt,int *obufpos,int crosbuf,int chans,int is_first_grain,dataptr dz)
  263. {
  264. int exit_status;
  265. int start_splice;
  266. int abs_splicelen = dz->iparam[GR_ABS_SPLICELEN];
  267. int abs_halfsplice = abs_splicelen/2; /* guaranteed to fall on stereo boundary */
  268. int halfsplice = dz->iparam[GR_SPLICELEN]/2;
  269. int splicestart_bufno = bufno;
  270. /* Write previously stored up_splice to THIS grain */
  271. if(*graincnt<dz->iparam[GR_KEEP] &&!is_first_grain) {
  272. if((exit_status = read_up_halfsplice(obufpos,abs_halfsplice,dz))<0)
  273. return(exit_status);
  274. }
  275. start_splice = ibufpos - abs_halfsplice; /* ALWAYS KEEP up_splice to NEXT grain */
  276. if(start_splice < 0) {
  277. splicestart_bufno = !bufno;
  278. start_splice += dz->buflen;
  279. }
  280. if((exit_status = store_up_halfsplice(1,start_splice,splicestart_bufno,chans,halfsplice,dz))<0)
  281. return(exit_status);
  282. if(*graincnt<dz->iparam[GR_KEEP]) {
  283. start_splice -= abs_halfsplice;
  284. if(start_splice < 0) {
  285. splicestart_bufno = !bufno;
  286. start_splice += dz->buflen;
  287. }
  288. if((exit_status = store_dn_halfsplice(start_splice,splicestart_bufno,chans,halfsplice,dz))<0)
  289. return(exit_status);
  290. if((exit_status = copy_start_of_grain(grainstart,start_splice,bufno,splicestart_bufno,obufpos,crosbuf,dz))<0)
  291. return(exit_status);
  292. if((exit_status = read_dn_halfsplice(obufpos,abs_halfsplice,dz))<0)
  293. return(exit_status);
  294. }
  295. if(++(*graincnt)>=dz->iparam[GR_OUT_OF])
  296. *graincnt = 0;
  297. return(FINISHED);
  298. }
  299. /************************* DO_THE_REORDERED_GRAINS *************************/
  300. int do_the_reordered_grains(int ibufpos,int bufno,int grainstart,int *graincnt,
  301. int *obufpos,int crosbuf,int chans,int is_first_grain,int is_last_grain,dataptr dz)
  302. {
  303. int exit_status;
  304. int n, m, k;
  305. int len;
  306. int abs_halfsplice = dz->iparam[GR_ABS_SPLICELEN]/2; /* guaranteed to fall on stereo boundary */
  307. if(*graincnt > dz->iparam[GR_REOLEN]) { /* WE'RE BEYOND PERMUTE-SET: LOOKING AT GRAINS NOT USED */
  308. if(*graincnt == dz->iparam[GR_REOSTEP]-1) { /* IF looking at very last unused grain */
  309. if((exit_status = store_upsplice_of_next_grain(ibufpos,bufno,abs_halfsplice,chans,dz))<0)
  310. return(exit_status);/* store startsplice of nextgrain, found at end of final skipped grain */
  311. *graincnt = -1; /* and reset grain counter to indicate end of skipped-over grains */
  312. } /* Otherwise, completely ignore skipped over grain */
  313. } else if(*graincnt == dz->iparam[GR_REOLEN]) { /* WE'VE REACHED THE END OF THE PERMUTABLE SET */
  314. for(n=0;n<dz->iparam[GR_REOCNT];n++) {
  315. k = dz->iparray[GR_REOSET][n]; /* write permuted set to outbuf */
  316. len = dz->lparray[GR_THIS_LEN][k];
  317. if((exit_status = copygrain_from_elsewhere(len,k,obufpos,dz))<0)
  318. return(exit_status);
  319. }
  320. if(dz->iparam[GR_REOSTEP] < dz->iparam[GR_REOLEN]) { /* IF NEXT PERMUTE SET BEGINS BEFORE END OF THIS */
  321. for(n=0,m=dz->iparam[GR_REOSTEP];m < dz->iparam[GR_REOLEN];n++,m++)
  322. swap_array_adresses_and_lens_for_reordr(n,m,dz); /* recycle the buffer storage */
  323. *graincnt = dz->iparam[GR_REOLEN] - dz->iparam[GR_REOSTEP]; /* & reduce graincnt to no. of reused grains */
  324. if((exit_status = put_grain_into_store(is_last_grain,ibufpos,bufno,grainstart,crosbuf,chans,*graincnt,dz))<0)
  325. return(exit_status); /* Store the current grain */
  326. } else if(dz->iparam[GR_REOSTEP] == dz->iparam[GR_REOLEN]) { /* IF IT BEGINS AT END OF THIS ONE */
  327. *graincnt = 0; /* reset grain counter to zero, for next set */
  328. if((exit_status = put_grain_into_store(is_last_grain,ibufpos,bufno,grainstart,crosbuf,chans,*graincnt,dz))<0)
  329. return(exit_status); /* Store the current grain */
  330. } else if (dz->iparam[GR_REOSTEP] == dz->iparam[GR_REOLEN]+1) {/* IF IT BEGINS AT 1st GRAIN BEYOND THIS SET */
  331. if((exit_status = store_upsplice_of_next_grain(ibufpos,bufno,abs_halfsplice,chans,dz))<0)
  332. return(exit_status);/* store startsplice of nextgrain, found at end of final skipped grain */
  333. *graincnt = -1; /* and reset grain counter to indicate end of skipped-over grains */
  334. } /* IF IT BEGINS BEYOND THAT : DO NOTHING */
  335. } else { /* WE'RE AT START OF, OR WITHIN, PERMUTABLE SET */
  336. if(is_first_grain) {
  337. if((exit_status = create_an_upsplice_from_pregrain_material(*obufpos,chans,dz))<0)
  338. return(exit_status); /* Generate upsplice to 1st grain, of correct size */
  339. memset((char *)dz->sampbuf[2],0,(size_t)dz->buflen * sizeof(float));
  340. *obufpos = 0;
  341. }
  342. if((exit_status = put_grain_into_store(is_last_grain,ibufpos,bufno,grainstart,crosbuf,chans,*graincnt,dz))<0)
  343. return(exit_status); /* Store the current grain */
  344. }
  345. (*graincnt)++;
  346. return(FINISHED);
  347. }
  348. /*********************** SYNCHRONISE_THE_GRAIN ***************************/
  349. int synchronise_the_grain(int ibufpos,int *graincnt,int bufno,int gapcnt,int *obufpos,
  350. int grainstart,int crosbuf,int chans,int *grainadjusted,int is_first_grain,dataptr dz)
  351. {
  352. int exit_status;
  353. int newgapcnt;
  354. int store_end = TRUE;
  355. if(*graincnt >= dz->iparam[GR_SYNCCNT])
  356. return(FINISHED);
  357. newgapcnt = round(dz->parray[GR_SYNCTIME][*graincnt]);
  358. if(*graincnt==0) {
  359. if((exit_status = retime_pre_firstgrain_material(newgapcnt,obufpos,chans,crosbuf,dz))<0)
  360. return(exit_status);
  361. (*graincnt)++;
  362. }
  363. newgapcnt = round(dz->parray[GR_SYNCTIME][*graincnt]);
  364. if((exit_status = retime_grain(ibufpos,newgapcnt,grainstart,gapcnt,
  365. bufno,obufpos,chans,crosbuf,grainadjusted,store_end,is_first_grain,dz))<0)
  366. return(exit_status);
  367. (*graincnt)++;
  368. return(CONTINUE);
  369. }
  370. /************************* DEAL_WITH_LAST_GRAINS *************************/
  371. //TW REVISED
  372. int deal_with_last_grains
  373. (int ibufpos,int bufno,int *graincnt,int grainstart,int *grainadjusted,
  374. int *obufpos,int crosbuf,int chans,double samptotime,int *is_first_grain,dataptr dz)
  375. {
  376. int exit_status;
  377. int is_last_grain = TRUE;
  378. int abs_splicelen = dz->iparam[GR_ABS_SPLICELEN];
  379. int abs_halfsplice = abs_splicelen/2; /* guaranteed to fall on stereo boundary */
  380. int halfsplice = dz->iparam[GR_SPLICELEN]/2;
  381. int n, start_splice, grainlen, orig_grainlen, new_grainlen;
  382. int splicestart_bufno;
  383. switch(dz->process) {
  384. case(GRAIN_COUNT):
  385. if(!dz->vflag[LOSE_LAST_GRAIN])
  386. (*graincnt)++;
  387. sprintf(errstr,"%d grains found at this gate level.\n",*graincnt);
  388. break;
  389. case(GRAIN_GET):
  390. if(!dz->vflag[LOSE_LAST_GRAIN]) {
  391. if((exit_status = store_the_grain_time(grainstart,graincnt,crosbuf,samptotime,0,dz))<0)
  392. return(exit_status);
  393. }
  394. for(n=0;n < *graincnt;n++)
  395. fprintf(dz->fp,"%lf\n",dz->parray[GR_SYNCTIME][n]);
  396. break;
  397. case(GRAIN_REVERSE):
  398. if((exit_status = save_abs_sampletime_of_grain(grainstart,graincnt,crosbuf,dz))<0)
  399. return(exit_status);
  400. if(*graincnt <= 1) {
  401. sprintf(errstr,"No grains found.\n");
  402. return(DATA_ERROR);
  403. }
  404. fprintf(stdout,"INFO: Reversing grain order\n");
  405. fflush(stdout);
  406. if((exit_status = do_the_reversing_process(*graincnt,obufpos,chans,dz))<0)
  407. return(exit_status);
  408. break;
  409. case(GRAIN_ALIGN):
  410. if(!dz->vflag[LOSE_LAST_GRAIN]) {
  411. if((exit_status = store_the_grain_time(grainstart,graincnt,crosbuf,samptotime,0,dz))<0)
  412. return(exit_status);
  413. }
  414. if(dz->iparam[GR_SYNCCNT] != *graincnt)
  415. dz->iparam[GR_SYNCCNT] = *graincnt;
  416. break;
  417. case(GRAIN_REORDER):
  418. if(!dz->vflag[LOSE_LAST_GRAIN]) {
  419. if((exit_status = do_the_reordered_grains
  420. (ibufpos,bufno,grainstart,graincnt,obufpos,crosbuf,chans,*is_first_grain,is_last_grain,dz))<0)
  421. return(exit_status);
  422. }
  423. if((exit_status = do_final_reorder_grains(*graincnt,obufpos,dz))<0)
  424. return(exit_status);
  425. break;
  426. case(GRAIN_RERHYTHM):
  427. case(GRAIN_TIMEWARP):
  428. case(GRAIN_POSITION):
  429. if(!dz->vflag[LOSE_LAST_GRAIN]) {
  430. if((exit_status = prepare_final_grain
  431. (ibufpos,&start_splice,bufno,&splicestart_bufno,grainstart,&grainlen,crosbuf,chans,dz))<0)
  432. return(exit_status);
  433. if(exit_status==FINISHED)
  434. break;
  435. if((exit_status = output_final_grain
  436. //TW REVISED
  437. (grainstart,start_splice,bufno,splicestart_bufno,*is_first_grain,obufpos,grainlen,crosbuf,dz))<0)
  438. return(exit_status);
  439. }
  440. break;
  441. case(GRAIN_OMIT):
  442. if(!dz->vflag[LOSE_LAST_GRAIN]
  443. && *graincnt<dz->iparam[GR_KEEP]) {
  444. if((exit_status = prepare_final_grain
  445. (ibufpos,&start_splice,bufno,&splicestart_bufno,grainstart,&grainlen,crosbuf,chans,dz))<0)
  446. return(exit_status);
  447. if(exit_status==FINISHED)
  448. break;
  449. if((exit_status = output_final_grain
  450. //TW REVISED
  451. (grainstart,start_splice,bufno,splicestart_bufno,*is_first_grain,obufpos,grainlen,crosbuf,dz))<0)
  452. return(exit_status);
  453. }
  454. break;
  455. case(GRAIN_DUPLICATE):
  456. if(!dz->vflag[LOSE_LAST_GRAIN]) {
  457. if((exit_status = duplicate_last_grain
  458. //TW REVISED
  459. (ibufpos,bufno,obufpos,grainstart,crosbuf,chans,*is_first_grain,dz))<0)
  460. return(exit_status);
  461. }
  462. break;
  463. case(GRAIN_REPITCH):
  464. if(!dz->vflag[LOSE_LAST_GRAIN]) {
  465. if((exit_status = repitching_process(ibufpos,bufno,grainstart,abs_halfsplice,halfsplice,graincnt,
  466. obufpos,&orig_grainlen,&new_grainlen,grainadjusted,is_first_grain,is_last_grain,chans,crosbuf,dz))<0)
  467. return(exit_status);
  468. }
  469. break;
  470. case(GRAIN_REMOTIF):
  471. if(!dz->vflag[LOSE_LAST_GRAIN]) {
  472. if((exit_status = repitching_and_retiming_process(ibufpos,bufno,grainstart,abs_halfsplice,halfsplice,graincnt,
  473. obufpos,&orig_grainlen,&new_grainlen,grainadjusted,is_first_grain,is_last_grain,chans,crosbuf,dz))<0)
  474. return(exit_status);
  475. }
  476. break;
  477. default:
  478. sprintf(errstr,"Unknown case in deal_with_last_grains()\n");
  479. return(PROGRAM_ERROR);
  480. }
  481. return(FINISHED);
  482. }
  483. /************************* DO_FINAL_REORDER_GRAINS *************************/
  484. int do_final_reorder_grains(int graincnt,int *obufpos,dataptr dz)
  485. {
  486. int exit_status;
  487. int n, k;
  488. int len;
  489. if(graincnt > 0 && graincnt <= dz->iparam[GR_REOCNT]) { /* There are grains still to permute */
  490. for(n=0;n<dz->iparam[GR_REOCNT];n++) {
  491. if((k = dz->iparray[GR_REOSET][n])>=graincnt) /* If required grain doesn't exist, finish */
  492. return(FINISHED);
  493. len = dz->lparray[GR_THIS_LEN][k];
  494. if((exit_status = copygrain_from_elsewhere(len,k,obufpos,dz))<0)
  495. return(exit_status);
  496. }
  497. }
  498. return(FINISHED);
  499. }
  500. /************************* DO_RERHYTHM_GRAIN *************************/
  501. int do_rerhythm_grain(int ibufpos,int *graincnt,int bufno,int gapcnt,
  502. int *obufpos,int grainstart,int crosbuf,int chans,int *grainadjusted,int is_first_grain,dataptr dz)
  503. {
  504. int exit_status;
  505. int newgapcnt, n;
  506. int store_end;
  507. double *ratio = dz->parray[GR_RATIO];
  508. switch(dz->mode) {
  509. case(GR_NO_REPEATS):
  510. store_end = TRUE;
  511. newgapcnt = round((double)(gapcnt/chans) * ratio[*graincnt]) * chans;
  512. if((exit_status = retime_grain
  513. (ibufpos,newgapcnt,grainstart,gapcnt,bufno,obufpos,chans,crosbuf,grainadjusted,store_end,is_first_grain,dz))<0)
  514. return(exit_status);
  515. if(++(*graincnt)>=dz->iparam[GR_RATIOCNT])
  516. *graincnt = 0;
  517. break;
  518. case(GR_REPEATS):
  519. store_end = FALSE;
  520. if(is_first_grain && dz->iparam[GR_RATIOCNT]>1) {
  521. if((exit_status = create_an_upsplice_from_pregrain_material(*obufpos,chans,dz))<0)
  522. return(exit_status);
  523. }
  524. for(n=0; n<dz->iparam[GR_RATIOCNT]-1; n++) {
  525. newgapcnt = round((double)(gapcnt/chans) * ratio[n]) * chans;
  526. if((exit_status = retime_grain
  527. (ibufpos,newgapcnt,grainstart,gapcnt,bufno,obufpos,chans,crosbuf,grainadjusted,store_end,is_first_grain,dz))<0)
  528. return(exit_status);
  529. is_first_grain = FALSE;
  530. }
  531. store_end = TRUE;
  532. newgapcnt = round((double)(gapcnt/chans) * ratio[n]) * chans;
  533. if((exit_status = retime_grain
  534. (ibufpos,newgapcnt,grainstart,gapcnt,bufno,obufpos,chans,crosbuf,grainadjusted,store_end,is_first_grain,dz))<0)
  535. return(exit_status);
  536. break;
  537. default:
  538. sprintf(errstr,"Unknown case in do_rerhythm_grain()\n");
  539. return(PROGRAM_ERROR);
  540. }
  541. return(FINISHED);
  542. }
  543. /************************* DUPLICATE_GRAIN *************************/
  544. int duplicate_grain(int ibufpos,int bufno,int gapcnt,int *obufpos,int grainstart,
  545. int crosbuf,int chans,int *grainadjusted,int is_first_grain,dataptr dz)
  546. {
  547. int exit_status;
  548. int newgapcnt = gapcnt, n;
  549. int store_end = FALSE;
  550. int dupl = (int)dz->iparam[GR_DUPLS];
  551. if(is_first_grain && dupl>1) {
  552. if((exit_status = create_an_upsplice_from_pregrain_material(*obufpos,chans,dz))<0)
  553. return(exit_status);
  554. }
  555. for(n=0; n<dupl-1; n++) {
  556. if((exit_status = retime_grain
  557. (ibufpos,newgapcnt,grainstart,gapcnt,bufno,obufpos,chans,crosbuf,grainadjusted,store_end,is_first_grain,dz))<0)
  558. return(exit_status);
  559. is_first_grain = FALSE;
  560. }
  561. store_end = TRUE;
  562. if((exit_status = retime_grain
  563. (ibufpos,newgapcnt,grainstart,gapcnt,bufno,obufpos,chans,crosbuf,grainadjusted,store_end,is_first_grain,dz))<0)
  564. return(exit_status);
  565. return(FINISHED);
  566. }
  567. /************************* DUPLICATE_LAST_GRAIN *************************/
  568. //TW REVISED
  569. int duplicate_last_grain(int ibufpos,int bufno,int *obufpos,int grainstart,
  570. int crosbuf,int chans,int is_first_grain,dataptr dz)
  571. {
  572. int exit_status;
  573. int /*newgapcnt = gapcnt,*/ n;
  574. /*int store_end = FALSE;*/
  575. int start_splice, grainlen;
  576. int splicestart_bufno;
  577. int dupl = (int)dz->iparam[GR_DUPLS];
  578. if(is_first_grain && dupl>1) {
  579. if((exit_status = create_an_upsplice_from_pregrain_material(*obufpos,chans,dz))<0)
  580. return(exit_status);
  581. }
  582. if((exit_status = prepare_final_grain
  583. (ibufpos,&start_splice,bufno,&splicestart_bufno,grainstart,&grainlen,crosbuf,chans,dz))<0)
  584. return(exit_status);
  585. if(exit_status==FINISHED)
  586. return(FINISHED);
  587. for(n=0; n<dupl; n++) {
  588. //TW REVISED
  589. if((exit_status = output_final_grain
  590. (grainstart,start_splice,bufno,splicestart_bufno,is_first_grain,obufpos,grainlen,crosbuf,dz))<0)
  591. return(exit_status);
  592. is_first_grain = FALSE;
  593. }
  594. return(FINISHED);
  595. }
  596. /************************** COPYGRAIN_FROM_ELSEWHERE ******************************/
  597. int copygrain_from_elsewhere(int len,int k,int *obufposition,dataptr dz)
  598. {
  599. int exit_status;
  600. register int n, obufpos = *obufposition;
  601. float *obuf = dz->sampbuf[2];
  602. float *buf = dz->extrabuf[k+SPLBUF_OFFSET];
  603. for(n=0;n<len;n++) {
  604. obuf[obufpos++] = buf[n];
  605. if(obufpos >= dz->buflen) {
  606. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  607. return(exit_status);
  608. obufpos = 0;
  609. }
  610. }
  611. *obufposition = obufpos;
  612. return(FINISHED);
  613. }
  614. /************************* SWAP_ARRAY_ADRESSES_AND_LENS_FOR_REORDR *************************
  615. *
  616. * The arrays still needed are now pointed to by the lower-indexed lparrays.
  617. * The arrays NO intER required get swapped, to be pointed to by the higher-indexed lparrays,
  618. * hence are overwritten as the process proceeds.
  619. *
  620. * This works (I hope) even where an index is swapped over more than once!!
  621. */
  622. void swap_array_adresses_and_lens_for_reordr(int n,int m,dataptr dz)
  623. {
  624. int n_bufno = n + SPLBUF_OFFSET;
  625. int m_bufno = m + SPLBUF_OFFSET;
  626. float *tempadr = dz->extrabuf[n_bufno];
  627. int temp_arraylen = dz->lparray[GR_ARRAYLEN][n];
  628. int templen = dz->lparray[GR_THIS_LEN][n];
  629. dz->extrabuf[n_bufno] = dz->extrabuf[m_bufno];
  630. dz->extrabuf[m_bufno] = tempadr;
  631. dz->lparray[GR_ARRAYLEN][n] = dz->lparray[GR_ARRAYLEN][m];
  632. dz->lparray[GR_ARRAYLEN][m] = temp_arraylen;
  633. dz->lparray[GR_THIS_LEN][n] = dz->lparray[GR_THIS_LEN][m];
  634. dz->lparray[GR_THIS_LEN][m] = templen;
  635. }
  636. /************************* COPY_GRAIN_TO_BUF *************************/
  637. int copy_grain_to_buf(int ibufpos,int bufno,int grainstart,int crosbuf,int chans,int storeno,dataptr dz)
  638. {
  639. int exit_status;
  640. int grainlen = ibufpos - grainstart;
  641. int storepos = 0, mid_grainlen;
  642. int abs_splicelen = dz->iparam[GR_ABS_SPLICELEN];
  643. int abs_halfsplice = abs_splicelen/2;
  644. int halfsplice = dz->iparam[GR_SPLICELEN]/2;
  645. int splicestart;
  646. int grainbufno = storeno + SPLBUF_OFFSET;
  647. int splicestart_bufno = bufno;
  648. if(crosbuf)
  649. grainlen += dz->buflen;
  650. if(grainlen > dz->lparray[GR_ARRAYLEN][storeno]) {
  651. if((dz->extrabuf[grainbufno] = (float *)realloc(dz->extrabuf[grainbufno],grainlen * sizeof(float)))==NULL) {
  652. sprintf(errstr,"INSUFFICIENT MEMORY to enlarge grain store.\n");
  653. return(MEMORY_ERROR);
  654. }
  655. dz->lparray[GR_ARRAYLEN][storeno] = grainlen;
  656. }
  657. dz->lparray[GR_THIS_LEN][storeno] = grainlen;
  658. if((exit_status = copy_up_halfsplice_to_grainstore(abs_halfsplice,grainbufno,grainlen,&storepos,dz))<0)
  659. return(exit_status);
  660. splicestart = ibufpos - abs_halfsplice;
  661. if(splicestart < 0) {
  662. splicestart += dz->buflen;
  663. splicestart_bufno = !bufno;
  664. }
  665. if((exit_status = store_up_halfsplice(1,splicestart,splicestart_bufno,chans,halfsplice,dz))<0)
  666. return(exit_status);
  667. splicestart -= abs_halfsplice;
  668. if(splicestart < 0) {
  669. splicestart += dz->buflen;
  670. splicestart_bufno = !bufno;
  671. }
  672. if((exit_status = store_dn_halfsplice(splicestart,splicestart_bufno,chans,halfsplice,dz))<0)
  673. return(exit_status);
  674. mid_grainlen = grainlen - dz->iparam[GR_ABS_SPLICELEN];
  675. if((exit_status = copy_midgrain_to_store(mid_grainlen,bufno,grainlen,grainstart,&storepos,crosbuf,grainbufno,dz))<0)
  676. return(exit_status);
  677. if((exit_status = copy_dn_halfsplice_to_grainstore(abs_halfsplice,grainbufno,grainlen,storepos,dz))<0)
  678. return(exit_status);
  679. return(FINISHED);
  680. }
  681. /************************* COPY_LAST_GRAIN_TO_BUF *************************/
  682. int copy_last_grain_to_buf(int ibufpos,int bufno,int grainstart,int crosbuf,int chans,int storeno,dataptr dz)
  683. {
  684. int exit_status;
  685. int storepos = 0, mid_grainlen;
  686. int splicelen, abs_splicelen = dz->iparam[GR_ABS_SPLICELEN];
  687. int abs_halfsplice = abs_splicelen/2;
  688. int splicestart;
  689. int splicestart_bufno = bufno;
  690. int grainbufno = storeno + SPLBUF_OFFSET;
  691. int storelen;
  692. int grainlen = ibufpos - grainstart;
  693. if(crosbuf)
  694. grainlen += dz->buflen;
  695. if((storelen = grainlen + abs_halfsplice)<abs_splicelen)
  696. storelen = abs_splicelen; /* grainstore must store up_hsplice & dn_hsplice even if grain to short */
  697. if(storelen > dz->lparray[GR_ARRAYLEN][storeno]) {
  698. if((dz->extrabuf[grainbufno] = (float *)realloc(dz->extrabuf[grainbufno],storelen * sizeof(float)))==NULL) {
  699. sprintf(errstr,"INSUFFICIENT MEMORY to enlarge grain store.\n");
  700. return(MEMORY_ERROR);
  701. }
  702. dz->lparray[GR_ARRAYLEN][storeno] = storelen;
  703. }
  704. dz->lparray[GR_THIS_LEN][storeno] = storelen;
  705. if((exit_status = copy_up_halfsplice_to_grainstore(abs_halfsplice,grainbufno,storelen,&storepos,dz))<0)
  706. return(exit_status);
  707. if((mid_grainlen = grainlen - abs_halfsplice) < 0)
  708. mid_grainlen = 0; /* HENCE mid_grainlen >= 0 */
  709. abs_splicelen = min(grainlen,abs_halfsplice);
  710. splicelen = abs_splicelen/chans;
  711. /* HENCE abs_splicelen <= grainlen */
  712. splicestart = ibufpos - abs_splicelen; /* splicestart >= grainstart, BECAUSE abs_splicelen <= grainlen */
  713. if(splicestart < 0) {
  714. splicestart += dz->buflen;
  715. splicestart_bufno = !bufno;
  716. }
  717. if((exit_status = store_dn_halfsplice(splicestart,splicestart_bufno,chans,splicelen,dz))<0)
  718. return(exit_status); /* forces an abs_halfsplice length unit, regardless of input splicelen */
  719. if(mid_grainlen > 0) {
  720. if((exit_status =
  721. copy_midgrain_to_store(mid_grainlen,bufno,storelen,grainstart,&storepos,crosbuf,grainbufno,dz))<0)
  722. return(exit_status);
  723. }
  724. if((exit_status = copy_dn_halfsplice_to_grainstore(abs_halfsplice,grainbufno,storelen,storepos,dz))<0)
  725. return(exit_status);
  726. return(FINISHED);
  727. }
  728. /************************ RETIME_PRE_FIRSTGRAIN_MATERIAL ***************************/
  729. int retime_pre_firstgrain_material
  730. (int new_grainstart,int *obufposition,int chans,int crosbuf,dataptr dz)
  731. {
  732. int exit_status;
  733. /*float *b = dz->sampbuf[bufno];*/ /* RWD: not used */
  734. float *obuf = dz->sampbuf[2];
  735. double *splicetab = dz->parray[GR_SPLICETAB];
  736. int excess, n, k;
  737. int m;
  738. int obufpos = *obufposition;
  739. int abs_splicelen = dz->iparam[GR_ABS_SPLICELEN]/2;
  740. int splicelen = abs_splicelen/chans;
  741. if(crosbuf) {
  742. sprintf(errstr,"1st grain starts beyond end of sound buffer: Can't proceed.\n");
  743. return(DATA_ERROR);
  744. }
  745. excess = new_grainstart - obufpos;
  746. if(excess > 0) {
  747. memmove((char *)dz->extrabuf[2],(char *)obuf,(size_t)dz->buflen * sizeof(float));
  748. if(excess >= dz->buflen) {
  749. memset((char *)obuf,0,(size_t)dz->buflen * sizeof(float));
  750. while(excess >= dz->buflen) {
  751. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  752. return(exit_status);
  753. excess -= dz->buflen;
  754. }
  755. }
  756. for(n=0;n<excess;n++)
  757. obuf[n] = 0;
  758. for(m=0;m < obufpos;m++) {
  759. obuf[n++] = dz->extrabuf[2][m];
  760. if(n >= dz->buflen) {
  761. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  762. return(exit_status);
  763. n = 0;
  764. }
  765. }
  766. new_grainstart = n;
  767. } else if(excess < 0) {
  768. for(n=0, m = excess; n < new_grainstart; n++, m++)
  769. obuf[n] = obuf[m]; /* Move data backwards */
  770. while(n < obufpos)
  771. obuf[n++] = 0; /* rezero samples beyond new_grainstart */
  772. k = 0;
  773. for(n=0;n<splicelen;n++) { /* Put splice on start of file */
  774. for(m=0;m<chans;m++) {
  775. obuf[k] = (float) /*round*/ ((double)obuf[k] * splicetab[n]);
  776. k++;
  777. }
  778. if(k >= dz->buflen) {
  779. sprintf(errstr,"Buffer accounting problem: retime_pre_firstgrain_material()\n");
  780. return(PROGRAM_ERROR);
  781. }
  782. }
  783. }
  784. *obufposition = new_grainstart; /* reset obuf pointer to (new) END of pre-grain material */
  785. return(FINISHED);
  786. }
  787. /************************* OUTPUT_GRAIN_LINK *************************/
  788. int output_grain_link(int thisgap,int abs_halfsplice,int *obufposition,dataptr dz)
  789. {
  790. int exit_status;
  791. int n, m;
  792. float *obuf = dz->sampbuf[2];
  793. int obufpos = *obufposition;
  794. for(n = 0, m = -(thisgap - abs_halfsplice); n < thisgap; n++,m++) {
  795. if(n < abs_halfsplice)
  796. obuf[obufpos] = dz->extrabuf[0][n];
  797. else
  798. obuf[obufpos] = 0;
  799. if(++obufpos >= dz->buflen) {
  800. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  801. return(exit_status);
  802. obufpos = 0;
  803. }
  804. }
  805. *obufposition = obufpos;
  806. return(FINISHED);
  807. }
  808. /************************* COPY_START_OF_GRAIN *************************/
  809. int copy_start_of_grain
  810. (int grainstart,int start_splice,int bufno,int splicestart_bufno,int *obufpos,int crosbuf,dataptr dz)
  811. {
  812. int exit_status;
  813. if(crosbuf) {
  814. if(splicestart_bufno != bufno) {
  815. if((exit_status = copygrain(grainstart,start_splice,!bufno,obufpos,dz))<0)
  816. return(exit_status);
  817. } else {
  818. if((exit_status = crosbuf_grain_type3(grainstart,start_splice,bufno,obufpos,dz))<0)
  819. return(exit_status);
  820. }
  821. } else {
  822. if((exit_status = copygrain(grainstart,start_splice,bufno,obufpos,dz))<0)
  823. return(exit_status);
  824. }
  825. return(FINISHED);
  826. }
  827. /************************** PREPARE_FINAL_GRAIN ******************************/
  828. int prepare_final_grain(int ibufpos,int *start_splice,int bufno,int *splicestart_bufno,
  829. int grainstart,int *grainlen,int crosbuf,int chans,dataptr dz)
  830. {
  831. int exit_status;
  832. int abs_splicelen = dz->iparam[GR_ABS_SPLICELEN];
  833. int abs_halfsplice = abs_splicelen/2; /* guaranteed to fall on stereo boundary */
  834. int halfsplice = abs_halfsplice/chans;
  835. *grainlen = ibufpos - grainstart;
  836. if(crosbuf)
  837. *grainlen += dz->buflen;
  838. if(*grainlen < abs_splicelen) {
  839. fprintf(stdout,"INFO: Final grain omitted: too short\n");
  840. fflush(stdout);
  841. return(FINISHED);
  842. }
  843. *start_splice = ibufpos - abs_halfsplice;
  844. *splicestart_bufno = bufno;
  845. if(*start_splice < 0) {
  846. *splicestart_bufno = !bufno;
  847. *start_splice += dz->buflen;
  848. }
  849. if((exit_status = store_dn_halfsplice(*start_splice,*splicestart_bufno,chans,halfsplice,dz))<0)
  850. return(exit_status);
  851. return(CONTINUE);
  852. }
  853. /************************** OUTPUT_FINAL_GRAIN ******************************/
  854. //TW REVISED
  855. int output_final_grain(int grainstart,int start_splice,int bufno,int splicestart_bufno,int is_first_grain,
  856. int *obufpos,int grainlen,int crosbuf,dataptr dz)
  857. {
  858. int exit_status;
  859. int abs_splicelen = dz->iparam[GR_ABS_SPLICELEN];
  860. int abs_halfsplice = abs_splicelen/2; /* guaranteed to fall on stereo boundary */
  861. if(!is_first_grain) {
  862. if((exit_status = read_up_halfsplice(obufpos,abs_halfsplice,dz))<0)
  863. return(exit_status);
  864. }
  865. if(grainlen > 0) {
  866. if((exit_status = copy_start_of_grain(grainstart,start_splice,bufno,splicestart_bufno,obufpos,crosbuf,dz))<0)
  867. return(exit_status);
  868. }
  869. if((exit_status = read_dn_halfsplice(obufpos,abs_halfsplice,dz))<0)
  870. return(exit_status);
  871. return(FINISHED);
  872. }
  873. /**************************** READ_DN_HALFSPLICE ****************************/
  874. int read_dn_halfsplice(int *obufposition,int len,dataptr dz)
  875. {
  876. int exit_status;
  877. int n, j = 0;
  878. float *b = dz->extrabuf[0];
  879. float *obuf = dz->sampbuf[2];
  880. int obufpos = *obufposition;
  881. for(n=0;n < len;n++) {
  882. obuf[obufpos++] = b[j++];
  883. if(obufpos >= dz->buflen) {
  884. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  885. return(exit_status);
  886. obufpos = 0;
  887. }
  888. }
  889. *obufposition = obufpos;
  890. return(FINISHED);
  891. }
  892. /**************************** READ_UP_HALFSPLICE ****************************/
  893. int read_up_halfsplice(int *obufposition,int len,dataptr dz)
  894. {
  895. int exit_status;
  896. int n, j = 0;
  897. float *b = dz->extrabuf[1];
  898. float *obuf = dz->sampbuf[2];
  899. int obufpos = *obufposition;
  900. for(n=0;n < len;n++) {
  901. obuf[obufpos++] = b[j++];
  902. if(obufpos >= dz->buflen) {
  903. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  904. return(exit_status);
  905. obufpos = 0;
  906. }
  907. }
  908. *obufposition = obufpos;
  909. return(FINISHED);
  910. }
  911. /**************************** COPY_UP_HALFSPLICE_TO_GRAINSTORE ****************************/
  912. int copy_up_halfsplice_to_grainstore(int len,int storeno,int storelen,int *storepos,dataptr dz)
  913. {
  914. char *goaladdress = (char *)dz->extrabuf[storeno];
  915. if(len > storelen) {
  916. sprintf(errstr,"Buffer anomaly: copy_up_halfsplice_to_grainstore()\n");
  917. return(PROGRAM_ERROR);
  918. }
  919. memmove(goaladdress,(char *)dz->extrabuf[1],len * sizeof(float));
  920. *storepos = len;
  921. return(FINISHED);
  922. }
  923. /**************************** COPY_DN_HALFSPLICE_TO_GRAINSTORE ****************************/
  924. int copy_dn_halfsplice_to_grainstore(int len,int storeno,int storelen,int storepos,dataptr dz)
  925. {
  926. char *goaladdress = (char *)(dz->extrabuf[storeno] + storepos);
  927. if(storepos + len > storelen) {
  928. sprintf(errstr,"Buffer anomaly: copy_dn_halfsplice_to_grainstore()\n");
  929. return(PROGRAM_ERROR);
  930. }
  931. memmove(goaladdress,(char *)dz->extrabuf[0],len * sizeof(float));
  932. return(FINISHED);
  933. }
  934. /**************************** CREATE_AN_UPSPLICE_FROM_PREGRAIN_MATERIAL ****************************/
  935. int create_an_upsplice_from_pregrain_material(int obufpos,int chans,dataptr dz)
  936. {
  937. int n, k;
  938. int m, j = 0, empty_space;
  939. double ratio;
  940. float *obuf = dz->sampbuf[2];
  941. float *splicebuf = dz->extrabuf[1];
  942. int abs_halfsplice = dz->iparam[GR_ABS_SPLICELEN]/2;
  943. int halfsplice = abs_halfsplice/chans;
  944. int splicelen;
  945. double *splicetab = dz->parray[GR_SPLICETAB];
  946. if(obufpos >= abs_halfsplice) {
  947. k = obufpos - abs_halfsplice;
  948. for(n=0;n<halfsplice;n++) {
  949. for(m=0;m<chans;m++)
  950. splicebuf[j++] = (float) /*round*/ ((double)obuf[k++] * splicetab[n]);
  951. if(k >= dz->buflen) {
  952. sprintf(errstr,"Error in buffer accounting: create_an_upsplice_from_pregrain_material()\n");
  953. return(PROGRAM_ERROR);
  954. }
  955. }
  956. } else {
  957. splicelen = obufpos/chans;
  958. empty_space = abs_halfsplice - obufpos;
  959. for(n=0;n<empty_space;n++)
  960. splicebuf[j++] = 0;
  961. k = 0;
  962. for(n=0;n<splicelen;n++) {
  963. ratio = (double)n/(double)splicelen;
  964. for(m=0;m<chans;m++)
  965. splicebuf[j++] = (float) /*round*/ ((double)obuf[k++] * ratio);
  966. if(k >= dz->buflen) {
  967. sprintf(errstr,"Error in buffer accounting: create_an_upsplice_from_pregrain_material()\n");
  968. return(PROGRAM_ERROR);
  969. }
  970. }
  971. }
  972. return(FINISHED);
  973. }
  974. /************************* RETIME_GRAIN *************************/
  975. int retime_grain(int ibufpos,int thisgap,int grainstart,int origgap,int bufno,
  976. int *obufpos,int chans,int crosbuf,int *grainadjusted,int store_end,int is_first_grain,dataptr dz)
  977. {
  978. int exit_status;
  979. int grainend, start_splice, gapchange;
  980. int abs_splicelen = dz->iparam[GR_ABS_SPLICELEN];
  981. int abs_halfsplice = abs_splicelen/2; /* guaranteed to fall on stereo boundary */
  982. int halfsplice = dz->iparam[GR_SPLICELEN]/2;
  983. int splicestart_bufno = bufno;
  984. start_splice = ibufpos - abs_halfsplice;
  985. if(start_splice < 0) {
  986. splicestart_bufno = !bufno;
  987. start_splice += dz->buflen;
  988. }
  989. if(!is_first_grain) {
  990. if((exit_status = read_up_halfsplice(obufpos,abs_halfsplice,dz))<0)
  991. return(exit_status);
  992. }
  993. if(store_end) {
  994. if((exit_status = store_up_halfsplice(1,start_splice,splicestart_bufno,chans,halfsplice,dz))<0)
  995. return(exit_status);
  996. }
  997. if((gapchange = thisgap - origgap)>=0) {
  998. start_splice -= abs_halfsplice;
  999. if(start_splice < 0) {
  1000. splicestart_bufno = !bufno;
  1001. start_splice += dz->buflen;
  1002. }
  1003. if((exit_status = store_dn_halfsplice(start_splice,splicestart_bufno,chans,halfsplice,dz))<0)
  1004. return(exit_status);
  1005. if((exit_status = copy_start_of_grain(grainstart,start_splice,bufno,splicestart_bufno,obufpos,crosbuf,dz))<0)
  1006. return(exit_status);
  1007. if((exit_status = output_grain_link(abs_halfsplice+gapchange,abs_halfsplice,obufpos,dz))<0)
  1008. return(exit_status);
  1009. } else {
  1010. if(thisgap < dz->iparam[GR_ABS_SPLICEX2]) {
  1011. grainend = grainstart + dz->iparam[GR_ABS_SPLICEX2];
  1012. (*grainadjusted)++;
  1013. } else
  1014. grainend = grainstart + thisgap;
  1015. start_splice = grainend - abs_splicelen; /* NB Ensures 1 grain stops before other starts */
  1016. splicestart_bufno = bufno;
  1017. if(crosbuf) {
  1018. if(start_splice >= dz->buflen)
  1019. start_splice -= dz->buflen;
  1020. else
  1021. splicestart_bufno = !bufno;
  1022. }
  1023. if((exit_status = store_dn_halfsplice(start_splice,splicestart_bufno,chans,halfsplice,dz))<0)
  1024. return(exit_status);
  1025. if((exit_status = copy_start_of_grain(grainstart,start_splice,bufno,splicestart_bufno,obufpos,crosbuf,dz))<0)
  1026. return(exit_status);
  1027. if((exit_status = output_grain_link(abs_halfsplice,abs_halfsplice,obufpos,dz))<0)
  1028. return(exit_status);
  1029. }
  1030. return(FINISHED);
  1031. }
  1032. /**************************** STORE_UP_HALFSPLICE ***************************
  1033. *
  1034. * GIVE IT bufno where splice STARTS!!!
  1035. */
  1036. int store_up_halfsplice(int storeno,int start,int bufno,int chans,int splicelen,dataptr dz)
  1037. {
  1038. int n, remain;
  1039. int m;
  1040. float *b = dz->sampbuf[bufno];
  1041. float *obuf = dz->extrabuf[storeno];
  1042. int k = start, j = 0;
  1043. double *splicetab = dz->parray[GR_SPLICETAB];
  1044. int true_halfsplice = dz->iparam[GR_SPLICELEN]/2;
  1045. if((remain = true_halfsplice - splicelen)<0) {
  1046. sprintf(errstr,"Invalid splicelen in store_up_halfsplice()\n");
  1047. return(PROGRAM_ERROR);
  1048. } else if(remain==0) {
  1049. for(n=0;n<splicelen;n++) {
  1050. for(m=0;m<chans;m++)
  1051. obuf[j++] = (float) /*round*/ ((double)b[k++] * splicetab[n]);
  1052. if(k >= dz->buflen) {
  1053. b = dz->sampbuf[!bufno];
  1054. k = 0;
  1055. }
  1056. }
  1057. } else {
  1058. for(n=0;n<remain;n++) {
  1059. for(m=0;m<chans;m++)
  1060. obuf[j++] = 0.0;
  1061. }
  1062. for(n=0;n<splicelen;n++) {
  1063. for(m=0;m<chans;m++)
  1064. obuf[j++] = (float) /*round*/ ((double)(b[k++] * n)/(double)splicelen);
  1065. if(k >= dz->buflen) {
  1066. b = dz->sampbuf[!bufno];
  1067. k = 0;
  1068. }
  1069. }
  1070. }
  1071. return(FINISHED);
  1072. }
  1073. /**************************** STORE_DN_HALFSPLICE ***************************
  1074. *
  1075. * GIVE IT bufno where splice STARTS!!!
  1076. */
  1077. int store_dn_halfsplice(int start,int bufno,int chans,int splicelen,dataptr dz)
  1078. {
  1079. int n, k = start, j = 0;
  1080. int m;
  1081. float *b = dz->sampbuf[bufno];
  1082. float *obuf = dz->extrabuf[0];
  1083. double *splicetab = dz->parray[GR_SPLICETAB];
  1084. int true_halfsplice = dz->iparam[GR_SPLICELEN]/2;
  1085. int remain = true_halfsplice - splicelen;
  1086. if(remain < 0) {
  1087. sprintf(errstr,"Invalid splicelen: store_dn_halfsplice()\n");
  1088. return(PROGRAM_ERROR);
  1089. } else if(remain==0) {
  1090. for(n=splicelen-1;n>=0;n--) {
  1091. for(m=0;m<chans;m++)
  1092. obuf[j++] = (float) /*round*/ ((double)b[k++] * splicetab[n]);
  1093. if(k >= dz->buflen) {
  1094. b = dz->sampbuf[!bufno];
  1095. k = 0;
  1096. }
  1097. }
  1098. } else {
  1099. for(n=splicelen-1;n>=0;n--) {
  1100. for(m=0;m<chans;m++)
  1101. obuf[j++] = (float) /*round*/ ((double)(b[k++] * n)/(double)splicelen);
  1102. if(k >= dz->buflen) {
  1103. b = dz->sampbuf[!bufno];
  1104. k = 0;
  1105. }
  1106. }
  1107. for(n=0;n<remain;n++) {
  1108. for(m=0;m<chans;m++)
  1109. obuf[j++] = 0.0;
  1110. }
  1111. }
  1112. return(FINISHED);
  1113. }
  1114. /**************************** COPY_MIDGRAIN_TO_STORE ***************************/
  1115. int copy_midgrain_to_store
  1116. (int mid_grainlen,int bufno,int storelen,int grainstart,int *storepos,int crosbuf,int storeno,dataptr dz)
  1117. {
  1118. float *b, *b2;
  1119. int /* j = *storepos,*/ partbuf, partbuf_samps;
  1120. if(mid_grainlen + *storepos > storelen) {
  1121. sprintf(errstr,"Buffer anomaly: copy_midgrain_to_store()\n");
  1122. return(PROGRAM_ERROR);
  1123. }
  1124. if(crosbuf) {
  1125. if(grainstart + mid_grainlen <= dz->buflen) {
  1126. b2 = dz->sampbuf[!bufno] + grainstart;
  1127. b = dz->extrabuf[storeno] + *storepos;
  1128. memmove((char *)b,(char *)b2,mid_grainlen * sizeof(float));
  1129. *storepos += mid_grainlen;
  1130. } else {
  1131. partbuf = dz->buflen - grainstart;
  1132. partbuf_samps = partbuf;
  1133. b2 = dz->sampbuf[!bufno] + grainstart;
  1134. b = dz->extrabuf[storeno] + *storepos;
  1135. memmove((char *)b,(char *)b2,partbuf_samps * sizeof(float));
  1136. *storepos += partbuf;
  1137. partbuf = mid_grainlen - partbuf;
  1138. partbuf_samps = partbuf;
  1139. b2 = dz->sampbuf[bufno];
  1140. b = dz->extrabuf[storeno] + *storepos;
  1141. memmove((char *)b,(char *)b2, partbuf_samps * sizeof(float));
  1142. *storepos += partbuf;
  1143. }
  1144. } else {
  1145. b2 = dz->sampbuf[bufno] + grainstart;
  1146. b = dz->extrabuf[storeno] + *storepos;
  1147. memmove((char *)b,(char *)b2,mid_grainlen * sizeof(float));
  1148. *storepos += mid_grainlen;
  1149. }
  1150. return(FINISHED);
  1151. }
  1152. /**************************** STORE_UPSPLICE_OF_NEXT_GRAIN ***************************/
  1153. int store_upsplice_of_next_grain(int ibufpos,int bufno,int abs_halfsplice,int chans,dataptr dz)
  1154. {
  1155. int splicestart_bufno = bufno;
  1156. int halfsplice = abs_halfsplice/chans;
  1157. int splicestart = ibufpos - abs_halfsplice;
  1158. if(splicestart < 0) {
  1159. splicestart += dz->buflen;
  1160. splicestart_bufno = !bufno;
  1161. }
  1162. return store_up_halfsplice(1,splicestart,splicestart_bufno,chans,halfsplice,dz);
  1163. }
  1164. /**************************** PUT_GRAIN_INTO_STORE ***************************/
  1165. int put_grain_into_store
  1166. (int is_last_grain,int ibufpos,int bufno,int grainstart,int crosbuf,int chans,int graincnt,dataptr dz)
  1167. {
  1168. if(is_last_grain)
  1169. return copy_last_grain_to_buf(ibufpos,bufno,grainstart,crosbuf,chans,graincnt,dz);
  1170. return copy_grain_to_buf(ibufpos,bufno,grainstart,crosbuf,chans,graincnt,dz);
  1171. }
  1172. /**************************** SAVE_ABS_SAMPLETIME_OF_GRAIN ***************************/
  1173. int save_abs_sampletime_of_grain(int grainstart,int *graincnt,int crosbuf,dataptr dz)
  1174. {
  1175. int samps_read_before_thisbuf = dz->total_samps_read - dz->ssampsread;
  1176. dz->lparray[GR_ABS_POS][*graincnt] = grainstart + samps_read_before_thisbuf;
  1177. if(crosbuf)
  1178. dz->lparray[GR_ABS_POS][*graincnt] -= dz->buflen;
  1179. (*graincnt)++;
  1180. if(*graincnt >= dz->iparam[GR_ARRAYSIZE]) {
  1181. dz->iparam[GR_ARRAYSIZE] += BIGARRAY;
  1182. if((dz->lparray[GR_ABS_POS] =
  1183. (int *)realloc(dz->lparray[GR_ABS_POS],dz->iparam[GR_ARRAYSIZE] * sizeof(int)))==NULL) {
  1184. sprintf(errstr,"INSUFFICIENT MEMORY to enlarge positions store.\n");
  1185. return(MEMORY_ERROR);
  1186. }
  1187. }
  1188. return(FINISHED);
  1189. }
  1190. /**************************** DO_THE_REVERSING_PROCESS ***************************/
  1191. int do_the_reversing_process(int graincnt,int *obufposition,int chans,dataptr dz)
  1192. {
  1193. int exit_status;
  1194. int obufpos = 0, seeksamps = 0, n, seekbufs = 0;
  1195. int abs_splicelen = dz->iparam[GR_ABS_SPLICELEN];
  1196. int abs_halfsplice = abs_splicelen/2;
  1197. int halfsplice = abs_halfsplice/chans;
  1198. int *grainpos;
  1199. if((exit_status = insert_EOF_sampletime_in_samptime_list(graincnt,dz))<0)
  1200. return(exit_status);
  1201. grainpos = dz->lparray[GR_ABS_POS];
  1202. for(n=0;n<graincnt;n++) /* adjust all grain-times to include start of splice */
  1203. grainpos[n] -= abs_halfsplice;
  1204. adjust_for_last_grain(&graincnt,grainpos,dz);
  1205. if((exit_status = clear_outbuf(dz))<0)
  1206. return(exit_status);
  1207. //TW UPDATE
  1208. /* AUGUST 2002 : go back to start of source and read first buffer (to reset dz->ssampsread) */
  1209. if(sndseekEx(dz->ifd[0],0,0) < 0) {
  1210. sprintf(errstr,"seek error at start of do_the_reversing_process()\n");
  1211. return(SYSTEM_ERROR);
  1212. }
  1213. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  1214. return(exit_status);
  1215. if((exit_status = do_seek_and_read(&seekbufs,&seeksamps,graincnt-1,dz))<0)
  1216. return(exit_status); /* seek to a buffer containing (WHOLE) final grain */
  1217. for(n=graincnt-1;n>=0;n--) {
  1218. if((exit_status = output_whole_grain
  1219. (n,&obufpos,&seeksamps,&seekbufs,halfsplice,abs_splicelen,chans,dz))<0)
  1220. return(exit_status);
  1221. }
  1222. *obufposition = obufpos;
  1223. return(FINISHED);
  1224. }
  1225. /**************************** DO_SEEK_AND_READ ***************************/
  1226. int do_seek_and_read(int *seekbufs,int *seeksamps,int grainno,dataptr dz)
  1227. {
  1228. int exit_status;
  1229. int new_seekbufs = dz->lparray[GR_ABS_POS][grainno]/dz->buflen;
  1230. if(new_seekbufs != *seekbufs) {
  1231. *seekbufs = new_seekbufs;
  1232. if((sndseekEx(dz->ifd[0],(*seekbufs) * dz->buflen,0))<0) {
  1233. sprintf(errstr,"seek error in do_seek_and_read()\n");
  1234. return(SYSTEM_ERROR);
  1235. }
  1236. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  1237. return(exit_status);
  1238. *seeksamps = *seekbufs * dz->buflen;
  1239. }
  1240. return(FINISHED);
  1241. }
  1242. /**************************** OUTPUT_UP_HALFSPLICE ****************************/
  1243. int output_up_halfsplice(int *ibufpos,int *obufpos,int chans,int splicelen,int *crosbuf,dataptr dz)
  1244. {
  1245. int exit_status;
  1246. int n, remain;
  1247. int m;
  1248. float *b = dz->sampbuf[0];
  1249. float *obuf = dz->sampbuf[2];
  1250. int i = *ibufpos;
  1251. int j = *obufpos;
  1252. double *splicetab = dz->parray[GR_SPLICETAB];
  1253. int true_halfsplice = dz->iparam[GR_SPLICELEN]/2;
  1254. if((remain = true_halfsplice - splicelen)<0) {
  1255. sprintf(errstr,"Invalid splicelen in output_up_halfsplice()\n");
  1256. return(PROGRAM_ERROR);
  1257. } else if(remain==0) {
  1258. for(n=0;n<splicelen;n++) {
  1259. for(m=0;m<chans;m++)
  1260. obuf[j++] = (float) /*round*/((double)b[i++] * splicetab[n]);
  1261. if((exit_status = test_buffer_overflows(obuf,&j,&i,n,splicelen-1,crosbuf,dz))<0)
  1262. return(exit_status);
  1263. }
  1264. } else {
  1265. for(n=0;n<remain;n++) {
  1266. for(m=0;m<chans;m++)
  1267. obuf[j++] = 0;
  1268. if(j >= dz->buflen) {
  1269. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1270. return(exit_status);
  1271. j = 0;
  1272. }
  1273. }
  1274. for(n=0;n<splicelen;n++) {
  1275. for(m=0;m<chans;m++)
  1276. obuf[j++] = (float) /*round*/ ((double)(b[i++] * n)/(double)splicelen);
  1277. if((exit_status = test_buffer_overflows(obuf,&j,&i,n,splicelen-1,crosbuf,dz))<0)
  1278. return(exit_status);
  1279. }
  1280. }
  1281. *ibufpos = i;
  1282. *obufpos = j;
  1283. return(FINISHED);
  1284. }
  1285. /**************************** OUTPUT_DN_HALFSPLICE ****************************/
  1286. int output_dn_halfsplice(int *ibufpos,int *obufpos,int chans,int splicelen,int *crosbuf,dataptr dz)
  1287. {
  1288. int exit_status;
  1289. int n, k, remain;
  1290. int m;
  1291. float *b = dz->sampbuf[0];
  1292. float *obuf = dz->sampbuf[2];
  1293. int i = *ibufpos;
  1294. int j = *obufpos;
  1295. double *splicetab = dz->parray[GR_SPLICETAB];
  1296. int true_halfsplice = dz->iparam[GR_SPLICELEN]/2;
  1297. if((remain = true_halfsplice - splicelen)<0) {
  1298. sprintf(errstr,"Invalid splicelen in output_dn_halfsplice()\n");
  1299. return(PROGRAM_ERROR);
  1300. } else if(remain==0) {
  1301. for(n=splicelen-1,k=0;n>=0;n--,k++) {
  1302. for(m=0;m<chans;m++)
  1303. obuf[j++] = (float) /*round */((double)b[i++] * splicetab[n]);
  1304. if((exit_status = test_buffer_overflows(obuf,&j,&i,k,splicelen-1,crosbuf,dz))<0)
  1305. return(exit_status);
  1306. }
  1307. } else {
  1308. for(n=splicelen-1,k=0;n>=0;n--,k++) {
  1309. for(m=0;m<chans;m++)
  1310. obuf[j++] = (float) /*round*/ ((double)(b[i++] * n)/(double)splicelen);
  1311. if((exit_status = test_buffer_overflows(obuf,&j,&i,k,splicelen-1,crosbuf,dz))<0)
  1312. return(exit_status);
  1313. }
  1314. for(n=0;n<remain;n++) {
  1315. for(m=0;m<chans;m++)
  1316. obuf[j++] = 0;
  1317. if(j >= dz->buflen) {
  1318. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1319. return(exit_status);
  1320. j = 0;
  1321. }
  1322. }
  1323. }
  1324. *ibufpos = i;
  1325. *obufpos = j;
  1326. return(FINISHED);
  1327. }
  1328. /**************************** DO_IN_SITU_HALFSPLICE_ON_STORED_GRAIN ****************************/
  1329. int do_in_situ_halfsplice_on_stored_grain(int bufpos,int chans,int splicelen,int grainstorelen,dataptr dz)
  1330. {
  1331. int n, k, remain;
  1332. int m;
  1333. float *obuf = dz->extrabuf[2];
  1334. double *splicetab = dz->parray[GR_SPLICETAB];
  1335. int true_halfsplice = dz->iparam[GR_SPLICELEN]/2;
  1336. int abs_halfsplice = true_halfsplice * chans;
  1337. if(bufpos + abs_halfsplice > grainstorelen) {
  1338. sprintf(errstr,"Grainstore buffer overflow: do_in_situ_halfsplice_on_stored_grain()\n");
  1339. return(PROGRAM_ERROR);
  1340. }
  1341. if((remain = true_halfsplice - splicelen)<0) {
  1342. sprintf(errstr,"Invalid splicelen in do_in_situ_halfsplice_on_stored_grain()\n");
  1343. return(PROGRAM_ERROR);
  1344. } else if(remain==0) {
  1345. for(n=splicelen-1,k=0;n>=0;n--,k++) {
  1346. for(m=0;m<chans;m++) {
  1347. obuf[bufpos] = (float) /*round*/((double)obuf[bufpos] * splicetab[n]);
  1348. bufpos++;
  1349. }
  1350. }
  1351. } else {
  1352. for(n=splicelen-1,k=0;n>=0;n--,k++) {
  1353. for(m=0;m<chans;m++) {
  1354. obuf[bufpos] = (float) /*round*/ ((double)(obuf[bufpos] * n)/(double)splicelen);
  1355. bufpos++;
  1356. }
  1357. }
  1358. for(n=0;n<remain;n++) {
  1359. for(m=0;m<chans;m++)
  1360. obuf[bufpos++] = 0.0;
  1361. }
  1362. }
  1363. return(FINISHED);
  1364. }
  1365. /**************************** TEST_BUFFER_OVERFLOWS ****************************/
  1366. int test_buffer_overflows(float *obuf,int *obufpos,int *ibufpos,int n,int maxlen,int *crosbuf,dataptr dz)
  1367. {
  1368. int exit_status;
  1369. if(*obufpos >= dz->buflen) {
  1370. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1371. return(exit_status);
  1372. *obufpos = 0;
  1373. }
  1374. if(*ibufpos >= dz->ssampsread && n < maxlen) {
  1375. if(*crosbuf) {
  1376. sprintf(errstr,"double crosbuf: test_buffer_overflows()\n");
  1377. return(PROGRAM_ERROR);
  1378. }
  1379. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  1380. return(exit_status);
  1381. *crosbuf = TRUE;
  1382. *ibufpos = 0;
  1383. }
  1384. return(FINISHED);
  1385. }
  1386. /**************************** COPY_MIDGRAIN_TO_OUTPUT ***************************/
  1387. int copy_midgrain_to_output(int mid_grainlen,int *ibufpos,int *obufpos,int *crosbuf,int chans,dataptr dz)
  1388. {
  1389. int exit_status;
  1390. int n;
  1391. int m;
  1392. float *b = dz->sampbuf[0], *obuf = dz->sampbuf[2];
  1393. int i = *ibufpos;
  1394. int j = *obufpos;
  1395. mid_grainlen /= chans;
  1396. for(n=0; n<mid_grainlen;n++) {
  1397. for(m=0;m<chans;m++)
  1398. obuf[j++] = b[i++];
  1399. if((exit_status = test_buffer_overflows(obuf,&j,&i,n,mid_grainlen-1,crosbuf,dz))<0)
  1400. return(exit_status);
  1401. }
  1402. *obufpos = j;
  1403. *ibufpos = i;
  1404. return(FINISHED);
  1405. }
  1406. /**************************** INSERT_EOF_SAMPLETIME_IN_SAMPTIME_LIST ***************************/
  1407. int insert_EOF_sampletime_in_samptime_list(int graincnt,dataptr dz)
  1408. {
  1409. if(graincnt+1 > dz->iparam[GR_ARRAYSIZE]) {
  1410. if((dz->lparray[GR_ABS_POS] =
  1411. (int *)realloc(dz->lparray[GR_ABS_POS],(graincnt+1) * sizeof(int)))==NULL) {
  1412. sprintf(errstr,"INSUFFICIENT MEMORY to enlarge positions store.\n");
  1413. return(MEMORY_ERROR);
  1414. }
  1415. }
  1416. dz->lparray[GR_ABS_POS][graincnt] = dz->insams[0];
  1417. return(FINISHED);
  1418. }
  1419. /**************************** ADJUST_FOR_LAST_GRAIN ***************************/
  1420. void adjust_for_last_grain(int *graincnt,int *grainpos,dataptr dz)
  1421. {
  1422. int lastgap;
  1423. if(dz->vflag[LOSE_LAST_GRAIN]) /* get rid of last grain if flagged */
  1424. (*graincnt)--;
  1425. else if((lastgap = grainpos[*graincnt] - grainpos[(*graincnt)-1]) < dz->iparam[GR_ABS_SPLICELEN]) {
  1426. fprintf(stdout,"WARNING: Loosing last grain: too short.\n");
  1427. fflush(stdout);
  1428. (*graincnt)--;
  1429. } else if(lastgap > dz->buflen) { /* truncate last grain if too int */
  1430. fprintf(stdout,"WARNING: Last grain truncated: too int.\n");
  1431. fflush(stdout);
  1432. grainpos[*graincnt] = grainpos[(*graincnt)-1] + dz->buflen;
  1433. }
  1434. }
  1435. /**************************** CLEAR_OUTBUF ***************************/
  1436. int clear_outbuf(dataptr dz)
  1437. {
  1438. memset((char *)dz->sampbuf[2],0,dz->buflen * sizeof(float));
  1439. return(FINISHED);
  1440. }
  1441. /**************************** OUTPUT_WHOLE_GRAIN ***************************/
  1442. int output_whole_grain(int n,int *obufpos,int *seeksamps,int *seekbufs,
  1443. int halfsplice,int abs_splicelen,int chans,dataptr dz)
  1444. {
  1445. int exit_status;
  1446. int crosbuf = FALSE;
  1447. int ibufpos;
  1448. int mid_grainlen;
  1449. int startsplice;
  1450. int endsplice;
  1451. startsplice = endsplice = halfsplice;
  1452. if((ibufpos = dz->lparray[GR_ABS_POS][n] - *seeksamps)<0) { /* IF current grain NOT in current buffer */
  1453. if(*seeksamps==0) { /* IF at start of file */
  1454. if((exit_status = adjust_firstgrain_upsplice(&ibufpos,&startsplice,n,chans))<0)
  1455. return(exit_status);
  1456. } else { /* ELSE: change current buffer */
  1457. if((exit_status = do_seek_and_read(seekbufs,seeksamps,n,dz))<0)
  1458. return(exit_status);
  1459. ibufpos = dz->lparray[GR_ABS_POS][n] - *seeksamps;
  1460. }
  1461. }
  1462. if((exit_status = output_up_halfsplice(&ibufpos,obufpos,chans,startsplice,&crosbuf,dz))<0)
  1463. return(exit_status);
  1464. mid_grainlen = (dz->lparray[GR_ABS_POS][n+1] - dz->lparray[GR_ABS_POS][n]) - abs_splicelen;
  1465. if(crosbuf) {
  1466. (*seekbufs)++;
  1467. (*seeksamps) += dz->buflen;
  1468. }
  1469. crosbuf = FALSE;
  1470. if(mid_grainlen > 0) {
  1471. if((exit_status = copy_midgrain_to_output(mid_grainlen,&ibufpos,obufpos,&crosbuf,chans,dz))<0)
  1472. return(exit_status);
  1473. if(crosbuf) {
  1474. (*seekbufs)++;
  1475. (*seeksamps) += dz->buflen;
  1476. }
  1477. }
  1478. crosbuf = FALSE;
  1479. if((exit_status = output_dn_halfsplice(&ibufpos,obufpos,chans,endsplice,&crosbuf,dz))<0)
  1480. return(exit_status);
  1481. if(crosbuf) {
  1482. (*seekbufs)++;
  1483. (*seeksamps) += dz->buflen;
  1484. }
  1485. return(FINISHED);
  1486. }
  1487. /**************************** ADJUST_FIRSTGRAIN_UPSPLICE ***************************/
  1488. int adjust_firstgrain_upsplice(int *ibufpos,int *startsplice,int n,int chans)
  1489. {
  1490. if(n!=0) { /* MUST be 1st grain */
  1491. sprintf(errstr,"Grain accounting error: adjust_firstgrain_upsplice()\n");
  1492. return(PROGRAM_ERROR);
  1493. }
  1494. *startsplice += *ibufpos/chans; /* shorten startsplice by deficit of [stereo] samples */
  1495. *ibufpos = 0; /* reset output read to start of file */
  1496. return(FINISHED);
  1497. }
  1498. /************************* DO_GRAIN_REPITCHING *************************/
  1499. /* RWD 4:2002 : NB modified to allow n-channels */
  1500. int do_grain_repitching(int *actual_grainlen,int bufno,int grainstart,int new_grainlen,int orig_grainlen,
  1501. int chans,int crosbuf,double pichratio,dataptr dz)
  1502. {
  1503. int exit_status;
  1504. int m;
  1505. int k = 0, here, thishere;
  1506. double dpoint = 0.0, frac;
  1507. //TW CHANGED
  1508. // float /*thisval[2],*/ nextval[2], diff[2];
  1509. float /*thisval[2],*/ nextval, diff;
  1510. float *b, *b2, *grainbuf = dz->extrabuf[2];
  1511. float *thisval;
  1512. thisval = (float *) malloc(chans * sizeof(float));
  1513. if(thisval==NULL) {
  1514. sprintf(errstr,"INSUFFICIENT MEMORY to enlarge positions store.\n");
  1515. return MEMORY_ERROR;
  1516. }
  1517. if(crosbuf)
  1518. b = dz->sampbuf[!bufno];
  1519. else
  1520. b = dz->sampbuf[bufno];
  1521. orig_grainlen /= chans;
  1522. while(k < new_grainlen) {
  1523. here = (int)dpoint; /* truncate */
  1524. frac = dpoint - (double)here;
  1525. thishere = (here*chans);
  1526. thishere += grainstart;
  1527. if((exit_status = test_for_bufcros(&thishere,&b,bufno,crosbuf,dz))<0) {
  1528. free(thisval);
  1529. return(exit_status);
  1530. }
  1531. if(exit_status == TRUE) /* changed buffer */
  1532. grainstart -= dz->buflen;
  1533. for(m=0;m<chans;m++)
  1534. thisval[m] = b[thishere+m];
  1535. b2 = b;
  1536. here++;
  1537. thishere = (here*chans);
  1538. thishere += grainstart;
  1539. if((exit_status = test_for_bufcros(&thishere,&b2,bufno,crosbuf,dz))<0) {
  1540. free(thisval);
  1541. return(exit_status);
  1542. }
  1543. for(m=0;m<chans;m++) {
  1544. //TW MODIFIED
  1545. nextval = b2[thishere+m];
  1546. diff = nextval - thisval[m];
  1547. grainbuf[k++] = (float) /*round*/(((double)diff * frac) + thisval[m]);
  1548. }
  1549. if((dpoint += pichratio) > orig_grainlen)
  1550. break;
  1551. }
  1552. *actual_grainlen = k;
  1553. free(thisval);
  1554. return(FINISHED);
  1555. }
  1556. /************************* TEST_FOR_BUFCROS *************************/
  1557. int test_for_bufcros(int *thishere,float **b,int bufno,int crosbuf,dataptr dz)
  1558. {
  1559. if(*thishere >= dz->buflen) {
  1560. if(crosbuf==FALSE) {
  1561. sprintf(errstr,"Buffer accounting problem: test_for_bufcros()\n");
  1562. return(PROGRAM_ERROR);
  1563. }
  1564. *b = dz->sampbuf[bufno];
  1565. *thishere -= dz->buflen;
  1566. return(TRUE);
  1567. }
  1568. return(FALSE);
  1569. }
  1570. /************************* SAVE_NEXTGRAIN_UPSPLICE_ELSEWHERE *************************/
  1571. int save_nextgrain_upsplice_elsewhere
  1572. (int ibufpos,int bufno,int abs_halfsplice,int halfsplice,int chans,dataptr dz)
  1573. {
  1574. int splicestart_bufno = bufno;
  1575. int start_splice = ibufpos - abs_halfsplice;
  1576. if(start_splice < 0) {
  1577. splicestart_bufno = !bufno;
  1578. start_splice += dz->buflen;
  1579. }
  1580. return store_up_halfsplice(0,start_splice,splicestart_bufno,chans,halfsplice,dz);
  1581. }
  1582. /************************* COPYGRAIN_FROM_GRAINBUF_TO_OUTBUF *************************/
  1583. int copygrain_from_grainbuf_to_outbuf(int *obufpos,int grainlen,dataptr dz)
  1584. {
  1585. int exit_status;
  1586. int remain = dz->buflen - *obufpos;
  1587. float *there = dz->sampbuf[2] + *obufpos;
  1588. float *here = dz->extrabuf[2];
  1589. while(grainlen >= remain) {
  1590. memmove((char *)there,(char *)here,remain * sizeof(float));
  1591. if((exit_status = write_samps(dz->sampbuf[2],dz->buflen,dz))<0)
  1592. return(exit_status);
  1593. *obufpos = 0;
  1594. there = dz->sampbuf[2];
  1595. here += remain;
  1596. grainlen -= remain;
  1597. remain = dz->buflen;
  1598. }
  1599. if(grainlen) {
  1600. memmove((char *)there,(char *)here,grainlen * sizeof(float));
  1601. *obufpos += grainlen;
  1602. }
  1603. return(FINISHED);
  1604. }
  1605. /************************* RETRIEVE_UPSPLICE_FOR_NEXTGRAIN *************************/
  1606. int retrieve_upsplice_for_nextgrain(int abs_halfsplice,dataptr dz)
  1607. {
  1608. memmove((char *)dz->extrabuf[1],(char *)dz->extrabuf[0],abs_halfsplice * sizeof(float));
  1609. return(FINISHED);
  1610. }
  1611. /************************* RETIME_MAIN_BODY_OF_GRAIN *************************/
  1612. //TW REVISED
  1613. int retime_main_body_of_grain(int grainstart,int bufno,double pichratio,
  1614. double timeratio,int chans,int crosbuf,int *grainadjusted,
  1615. int orig_grainlen,int *new_grainlen,dataptr dz)
  1616. {
  1617. int exit_status;
  1618. int abs_splicelen = dz->iparam[GR_ABS_SPLICELEN];
  1619. int abs_halfsplice = abs_splicelen/2; /* guaranteed to fall on stereo boundary */
  1620. int halfsplice = dz->iparam[GR_SPLICELEN]/2;
  1621. *new_grainlen = round((double)(orig_grainlen/chans) * timeratio) * chans;
  1622. if(*new_grainlen < dz->iparam[GR_ABS_SPLICEX2]) {
  1623. *new_grainlen = dz->iparam[GR_ABS_SPLICEX2];
  1624. (*grainadjusted)++;
  1625. }
  1626. *new_grainlen -= abs_halfsplice;
  1627. orig_grainlen -= abs_halfsplice;
  1628. if((exit_status = repitch_main_body_of_grain(bufno,grainstart,*new_grainlen,orig_grainlen,
  1629. pichratio,chans,crosbuf,halfsplice,abs_halfsplice,dz))<0)
  1630. return(exit_status);
  1631. return(FINISHED);
  1632. }
  1633. /************************* REPITCH_MAIN_BODY_OF_GRAIN *************************/
  1634. int repitch_main_body_of_grain(int bufno,int grainstart,int new_grainlen,int orig_grainlen,
  1635. double pichratio,int chans,int crosbuf,int halfsplice,int abs_halfsplice,dataptr dz)
  1636. {
  1637. int exit_status;
  1638. int actual_grainlen;
  1639. int splicelen;
  1640. int splicestart;
  1641. float *grainbuf;
  1642. if(new_grainlen > dz->iparam[GR_STORESIZE]) {
  1643. if((dz->extrabuf[2] = (float *)realloc(dz->extrabuf[2],new_grainlen * sizeof(float)))==NULL) {
  1644. sprintf(errstr,"INSUFFICIENT MEMORY to enlarge grain store.\n");
  1645. return(MEMORY_ERROR);
  1646. }
  1647. dz->iparam[GR_STORESIZE] = (int)new_grainlen;
  1648. }
  1649. grainbuf = dz->extrabuf[2];
  1650. memset((char *)grainbuf,0,new_grainlen * sizeof(float));
  1651. if((exit_status = do_grain_repitching
  1652. (&actual_grainlen,bufno,grainstart,new_grainlen,orig_grainlen,chans,crosbuf,pichratio,dz))<0)
  1653. return(exit_status);
  1654. splicelen = halfsplice;
  1655. splicestart = actual_grainlen - abs_halfsplice;
  1656. if(splicestart < 0) {
  1657. splicelen += splicestart/chans;
  1658. splicestart = 0;
  1659. }
  1660. return do_in_situ_halfsplice_on_stored_grain(splicestart,chans,splicelen,new_grainlen,dz);
  1661. }
  1662. /************************* CREATE_REPITCHED_AND_RETIMED_GRAIN *************************/
  1663. //TW REVISED
  1664. int create_repitched_and_retimed_grain
  1665. (int bufno,int grainstart,int orig_grainlen,int *new_grainlen,
  1666. double pichratio,double timeratio,int *obufpos,int *is_first_grain,
  1667. int *grainadjusted,int abs_halfsplice,int chans,int crosbuf,dataptr dz)
  1668. {
  1669. int exit_status;
  1670. if((exit_status = retime_main_body_of_grain(grainstart,bufno,pichratio,timeratio,
  1671. chans,crosbuf,grainadjusted,orig_grainlen,new_grainlen,dz))<0)
  1672. return(exit_status);
  1673. if(!(*is_first_grain)) {
  1674. if((exit_status = read_up_halfsplice(obufpos,abs_halfsplice,dz))<0)
  1675. return(exit_status);
  1676. }
  1677. *is_first_grain = FALSE;
  1678. return copygrain_from_grainbuf_to_outbuf(obufpos,*new_grainlen,dz);
  1679. }
  1680. /************************* SAVE_ORIGGRAIN_LENGTH_AND_STORE_NEXTGRAINS_UPSPLICE *************************/
  1681. int save_origgrain_length_and_store_nextgrains_upsplice(int *orig_grainlen,int ibufpos,int bufno,
  1682. int grainstart,int abs_halfsplice,int halfsplice,int crosbuf,int chans,int is_last_grain,dataptr dz)
  1683. {
  1684. *orig_grainlen = ibufpos - grainstart;
  1685. if(crosbuf)
  1686. *orig_grainlen += dz->buflen;
  1687. if((*orig_grainlen - abs_halfsplice)<0) {
  1688. if(!is_last_grain) {
  1689. sprintf(errstr,"Anomalous too short grain: save_origgrain_length_and_store_nextgrains_upsplice()\n");
  1690. return(PROGRAM_ERROR);
  1691. } else {
  1692. fprintf(stdout,"WARNING: Last grain omitted: too short.\n");
  1693. return(CONTINUE);
  1694. }
  1695. }
  1696. return save_nextgrain_upsplice_elsewhere(ibufpos,bufno,abs_halfsplice,halfsplice,chans,dz);
  1697. }
  1698. /************************* REPITCHING_PROCESS *************************/
  1699. int repitching_process(int ibufpos,int bufno,int grainstart,int abs_halfsplice,int halfsplice,int *graincnt,
  1700. int *obufpos,int *orig_grainlen,int *new_grainlen,int *grainadjusted,
  1701. int *is_first_grain,int is_last_grain,int chans,int crosbuf,dataptr dz)
  1702. {
  1703. int exit_status;
  1704. double timeratio = 1.0, pichratio;
  1705. int n;
  1706. if(*is_first_grain && (exit_status = create_an_upsplice_from_pregrain_material(*obufpos,chans,dz))<0)
  1707. return(exit_status);
  1708. if((exit_status = save_origgrain_length_and_store_nextgrains_upsplice
  1709. (orig_grainlen,ibufpos,bufno,grainstart,abs_halfsplice,halfsplice,crosbuf,chans,is_last_grain,dz))<0)
  1710. return(exit_status);
  1711. if(exit_status==CONTINUE) /* last grain too short */
  1712. return(FINISHED);
  1713. switch(dz->mode) {
  1714. case(GR_REPEATS):
  1715. for(n=0;n<dz->iparam[GR_RATIOCNT];n++) {
  1716. pichratio = dz->parray[GR_RATIO][n];
  1717. if((exit_status = create_repitched_and_retimed_grain
  1718. (bufno,grainstart,*orig_grainlen,new_grainlen,pichratio,timeratio,obufpos,
  1719. is_first_grain,grainadjusted,abs_halfsplice,chans,crosbuf,dz))<0)
  1720. return(exit_status);
  1721. }
  1722. break;
  1723. case(GR_NO_REPEATS):
  1724. pichratio = dz->parray[GR_RATIO][*graincnt];
  1725. if((exit_status = create_repitched_and_retimed_grain
  1726. (bufno,grainstart,*orig_grainlen,new_grainlen,pichratio,timeratio,obufpos,
  1727. is_first_grain,grainadjusted,abs_halfsplice,chans,crosbuf,dz))<0)
  1728. return(exit_status);
  1729. if(++(*graincnt)>=dz->iparam[GR_RATIOCNT])
  1730. *graincnt = 0;
  1731. break;
  1732. default:
  1733. sprintf(errstr,"Unknown case: repitching_process()\n");
  1734. return(PROGRAM_ERROR);
  1735. }
  1736. return(FINISHED);
  1737. }
  1738. /************************* REPITCHING_AND_RETIMING_PROCESS *************************/
  1739. int repitching_and_retiming_process(int ibufpos,int bufno,int grainstart,int abs_halfsplice,
  1740. int halfsplice,int *graincnt,int *obufpos,int *orig_grainlen,int *new_grainlen,int *grainadjusted,
  1741. int *is_first_grain,int is_last_grain,int chans,int crosbuf,dataptr dz)
  1742. {
  1743. int exit_status;
  1744. double timeratio, pichratio;
  1745. int n;
  1746. if(*is_first_grain && (exit_status = create_an_upsplice_from_pregrain_material(*obufpos,chans,dz))<0)
  1747. return(exit_status);
  1748. if((exit_status = save_origgrain_length_and_store_nextgrains_upsplice
  1749. (orig_grainlen,ibufpos,bufno,grainstart,abs_halfsplice,halfsplice,crosbuf,chans,is_last_grain,dz))<0)
  1750. return(exit_status);
  1751. if(exit_status==CONTINUE) /* last grain too short */
  1752. return(FINISHED);
  1753. switch(dz->mode) {
  1754. case(GR_REPEATS):
  1755. for(n=0;n<dz->iparam[GR_RATIOCNT];n+=2) {
  1756. pichratio = dz->parray[GR_RATIO][n];
  1757. timeratio = dz->parray[GR_RATIO][n+1];
  1758. if((exit_status = create_repitched_and_retimed_grain
  1759. (bufno,grainstart,*orig_grainlen,new_grainlen,pichratio,timeratio,obufpos,
  1760. is_first_grain,grainadjusted,abs_halfsplice,chans,crosbuf,dz))<0)
  1761. return(exit_status);
  1762. }
  1763. break;
  1764. case(GR_NO_REPEATS):
  1765. pichratio = dz->parray[GR_RATIO][(*graincnt)++];
  1766. timeratio = dz->parray[GR_RATIO][(*graincnt)++];
  1767. if((exit_status = create_repitched_and_retimed_grain
  1768. (bufno,grainstart,*orig_grainlen,new_grainlen,pichratio,timeratio,obufpos,
  1769. is_first_grain,grainadjusted,abs_halfsplice,chans,crosbuf,dz))<0)
  1770. return(exit_status);
  1771. if(*graincnt >= dz->iparam[GR_RATIOCNT])
  1772. *graincnt = 0;
  1773. break;
  1774. default:
  1775. sprintf(errstr,"Unknown case: repitching_and_retiming_process()\n");
  1776. return(PROGRAM_ERROR);
  1777. }
  1778. return(FINISHED);
  1779. }
  1780. /****************************** TIMESTRETCH_ITERATIVE ****************************/
  1781. int timestretch_iterative(dataptr dz)
  1782. {
  1783. int exit_status, do_slow = 0, do_regu;
  1784. float *ibuf = dz->sampbuf[0];
  1785. float *obuf = dz->sampbuf[1];
  1786. // double *peak = dz->parray[0];
  1787. int *pos = dz->lparray[0];
  1788. int peakcnt, startsearch, endsearch, local_minima_cnt, minimum_element_len;
  1789. int stretchable_len, required_segsection_len, total_segsection_length;
  1790. int element_cnt, max_elements_needed;
  1791. int arrsiz, fullperms, patternsize;
  1792. int *pattern;
  1793. int finished;
  1794. int n, k=0, outpos, startseg, startpos, endpos, seglen;
  1795. int abspos, new_abspos;
  1796. int ascatter = 0, pscatter = 0, jitter = 0;
  1797. double gain = 1.0, trans = 1.0, d, part, time, diff;
  1798. float val, nextval;
  1799. double z = (dz->param[RRR_END] - dz->param[RRR_START]) * dz->param[RRR_REPET];
  1800. double starttime_of_iter, davg_step;
  1801. int total_slolen, total_slo_incr, slo_incr, min_step, j, avg_step, gap, maxsamp = 0;
  1802. int *seg_step = NULL, *seg_len = NULL;
  1803. int thiselementcnt, regusegscnt, okcnt, *seg_ok = NULL;
  1804. if(dz->vflag[0] == 0)
  1805. z += dz->param[RRR_START];
  1806. if(dz->vflag[1] == 0)
  1807. z += dz->duration - dz->param[RRR_END];
  1808. //2010
  1809. dz->tempsize = (int)round(z * dz->infile->srate) * dz->infile->channels;
  1810. fprintf(stdout,"INFO: Generating output.\n");
  1811. fflush(stdout);
  1812. if(sloom)
  1813. display_virtual_time(0,dz);
  1814. if(dz->brksize[RRR_ASCAT] || !flteq(dz->param[RRR_ASCAT],0.0)) {
  1815. ascatter = 1;
  1816. jitter = 1;
  1817. }
  1818. if(dz->brksize[RRR_PSCAT] || !flteq(dz->param[RRR_PSCAT],0.0)) {
  1819. pscatter = 1;
  1820. jitter = 1;
  1821. }
  1822. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  1823. return(exit_status);
  1824. dz->sampbuf[0][dz->insams[0]] = dz->sampbuf[0][dz->insams[0] - 1]; /* wrap around point for interpolation */
  1825. startsearch = (int)round(dz->param[RRR_START] * dz->infile->srate);
  1826. endsearch = (int)round(dz->param[RRR_END] * dz->infile->srate);
  1827. /* FIND ALL POSITIVE PEAKS : always look only at +ve vals, so all zero-crossings eventually found will be from +ve to -ve */
  1828. peakcnt = 0;
  1829. if((exit_status = find_all_positive_peaks(startsearch,endsearch,&peakcnt,dz)) < 0)
  1830. return(exit_status);
  1831. /* FIND ALL POSITIVE-PEAK MINIMA : overwriting the arrays peak-vals & peak-position with minima-vals & minima-positions */
  1832. local_minima_cnt = 0;
  1833. if((exit_status = find_all_local_minima(peakcnt,&local_minima_cnt,dz)) < 0)
  1834. return(exit_status);
  1835. /* ELIMINATE SPURIOUS MINIMA */
  1836. if((exit_status = eliminate_spurious_minima(&local_minima_cnt,&minimum_element_len,dz)) < 0)
  1837. return (exit_status);
  1838. fprintf(stdout,"INFO: Original number of segments found = %d\n",local_minima_cnt - 1);
  1839. fflush(stdout);
  1840. /* CHECK MINIMA FOUND AGAINST INPUT ESTIMATE */
  1841. if((local_minima_cnt - 1) >= 2 * dz->iparam[RRR_GET]) {
  1842. if((exit_status = eliminate_excess_minima(&local_minima_cnt,pos,dz)) < 0)
  1843. return (exit_status);
  1844. fprintf(stdout,"INFO: Reduced to = %d\n",local_minima_cnt - 1);
  1845. fflush(stdout);
  1846. }
  1847. /* SEARCH FOR ZERO CROSSINGS AFTER MINIMA */
  1848. if((exit_status = locate_zero_crossings(local_minima_cnt,dz)) < 0)
  1849. return (exit_status);
  1850. /* CALCULATE HOW int STRETCHED SECTION SHOULD BE */
  1851. stretchable_len = pos[local_minima_cnt-1] - pos[0];
  1852. required_segsection_len = (int)round((double)stretchable_len * dz->param[RRR_STRETCH]);
  1853. /* CALCULATE HOW MANY ELEMENTS TO USE */
  1854. element_cnt = local_minima_cnt - 1;
  1855. max_elements_needed = (int)round(ceil((double)required_segsection_len/(double)minimum_element_len));
  1856. max_elements_needed *= 2; /* required no of elements is set to a value greater than possibly required */
  1857. /* CALCULATE HOW MANY PERMUTATIONS NEEDED */
  1858. arrsiz = element_cnt * dz->iparam[RRR_REPET]; /* if elements can be repeated N times, perm-array can contain N copies of values */
  1859. fullperms = max_elements_needed / arrsiz;
  1860. if(fullperms * arrsiz < max_elements_needed) /* total number of permutations to generate must include any part permutation */
  1861. fullperms++;
  1862. patternsize = fullperms * arrsiz;
  1863. if((pattern = (int *)malloc(patternsize * sizeof(int)))==NULL) {
  1864. sprintf(errstr,"Insufficient memory to generate segment permutation.\n");
  1865. return(MEMORY_ERROR);
  1866. }
  1867. /* GENERATE RANDOM PATTERN */
  1868. if((exit_status = rand_ints_with_restricted_repeats(element_cnt,max_elements_needed,arrsiz,fullperms,&pattern,dz)) < 0)
  1869. return(exit_status);
  1870. if(dz->brksize[RRR_SLOW]) {
  1871. maxsamp = (int)round(dz->maxtime * (double)dz->infile->srate);
  1872. if((seg_step = (int *)malloc(element_cnt * sizeof(int)))==NULL) {
  1873. sprintf(errstr,"Insufficient memory to store steps between segment if slowed.\n");
  1874. return(MEMORY_ERROR);
  1875. }
  1876. if(dz->brksize[RRR_REGU]) {
  1877. if((seg_len = (int *)malloc(element_cnt * sizeof(int)))==NULL) {
  1878. sprintf(errstr,"Insufficient memory to store orig segment lengths, if slowed.\n");
  1879. return(MEMORY_ERROR);
  1880. }
  1881. if((seg_ok = (int *)malloc(element_cnt * sizeof(int)))==NULL) {
  1882. sprintf(errstr,"Insufficient memory to store segment flags, if regularised.\n");
  1883. return(MEMORY_ERROR);
  1884. }
  1885. }
  1886. }
  1887. /* COPY SOUND START TO OUTBUF */
  1888. outpos = 0;
  1889. if(dz->vflag[0] == 0) {
  1890. memcpy((char *)obuf,(char *)ibuf,pos[0] * sizeof(float));
  1891. outpos = pos[0];
  1892. }
  1893. /* GENERATE OUTPUT SEQUENCE OF ELEMENTS */
  1894. total_segsection_length = 0;
  1895. finished = 0;
  1896. time = 0.0;
  1897. abspos = dz->total_samps_written + outpos;
  1898. if(dz->brksize[RRR_SLOW])
  1899. maxsamp += abspos;
  1900. starttime_of_iter = (double)abspos/(double)dz->infile->srate;
  1901. do {
  1902. for(n=0; n < patternsize; n++) {
  1903. if(n % element_cnt == 0) {
  1904. do_slow = 0;
  1905. do_regu = 0;
  1906. if(dz->brksize[RRR_SLOW]) {
  1907. time = (double)abspos/(double)dz->infile->srate;
  1908. time -= starttime_of_iter;
  1909. if((exit_status = read_value_from_brktable(time,RRR_SLOW,dz))<0)
  1910. return(exit_status);
  1911. if(dz->brksize[RRR_REGU] > 0) {
  1912. if((exit_status = read_value_from_brktable(time,RRR_REGU,dz))<0)
  1913. return(exit_status);
  1914. }
  1915. }
  1916. if(dz->param[RRR_SLOW] > 1.0) { // If segments are to be slowed (by intervening silence)
  1917. do_slow = 1;
  1918. while(do_slow) {
  1919. thiselementcnt = min(element_cnt,patternsize-n); // SAFETY (should be whole number of element_cnts in patternsize)
  1920. total_slolen = (int)round(stretchable_len * dz->param[RRR_SLOW]); // Sample duration of all segs, once slowed by intervening gaps
  1921. total_slo_incr = total_slolen - stretchable_len; // Total added silence, in samples
  1922. slo_incr = (int)round((double)total_slo_incr/(double)thiselementcnt); // Silence to be inserted after to each element
  1923. if(slo_incr <= 0) {
  1924. do_slow = 0;
  1925. break;
  1926. } // Regularisation of rhythm of output cannot be done until there is
  1927. if(dz->param[RRR_REGU] > 0.0) { // maniupulable silence between segments, which only occues after SLOW applied
  1928. do_regu = 1;
  1929. while(do_regu) {
  1930. total_slo_incr = slo_incr * thiselementcnt; // Total added silence, after accounting for rounding
  1931. min_step = dz->insams[0] + 1;
  1932. avg_step = 0;
  1933. for(j = 0,k=n; j < thiselementcnt;j++,k++){
  1934. startseg = pattern[k];
  1935. startpos = pos[startseg];
  1936. endpos = pos[startseg+1];
  1937. seglen = endpos - startpos;
  1938. seg_len[j] = seglen; // Find actual length of each segment
  1939. seg_step[j] = seg_len[j] + slo_incr; // Find step between start of one seg & next (when intervening silence added) BEFORE REGULARISING
  1940. seg_ok[j] = 1; // Mark as a valid segment to regularise
  1941. min_step = min(min_step,seg_step[j]); // Find the minimim step
  1942. avg_step += seg_step[j]; // Find the average step
  1943. }
  1944. regusegscnt = 0;
  1945. okcnt = thiselementcnt;
  1946. davg_step = (double)avg_step/(double)okcnt; // Once regularised, step between seg entries will be set to the average value
  1947. for(j=0; j < thiselementcnt; j++) { // If length of a segment is > average, this can't be done
  1948. if(seg_len[j] > davg_step) { // So mark any such segment as not valid for the averaging process
  1949. seg_ok[j] = 0;
  1950. avg_step -= seg_len[j]; // and remove it from the calculation of the average step
  1951. okcnt--;
  1952. davg_step = (double)avg_step/(double)okcnt;
  1953. } else
  1954. regusegscnt++; // Count all the averagable segments
  1955. }
  1956. if(regusegscnt < 2) // If less than 2 valid segs, no averaging can be done
  1957. do_regu = 0;
  1958. break;
  1959. }
  1960. if(do_regu) {
  1961. avg_step = (int)round((double)avg_step/(double)regusegscnt);
  1962. for(j=0; j < thiselementcnt; j++) { // For all valid segments
  1963. if(seg_ok[j]) // (partially) adjust step between it and next to the average step
  1964. seg_step[j] = ((int)round((avg_step - seg_step[j]) * dz->param[RRR_REGU])) + seg_step[j];
  1965. }
  1966. }
  1967. }
  1968. break;
  1969. }
  1970. if(do_slow) {
  1971. if(do_regu) {
  1972. for(j=0; j < thiselementcnt; j++) // Find the gap left after each segment
  1973. seg_step[j] -= seg_len[j];
  1974. } else { // If seg_entries NOT to be regularised
  1975. for(j=0; j < thiselementcnt; j++) // Set silent gap between segs all to same val
  1976. seg_step[j] = slo_incr;
  1977. }
  1978. }
  1979. }
  1980. }
  1981. startseg = pattern[n];
  1982. startpos = pos[startseg];
  1983. endpos = pos[startseg+1];
  1984. seglen = endpos - startpos;
  1985. if(jitter) {
  1986. time = (double)abspos/(double)dz->infile->srate;
  1987. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  1988. return(exit_status);
  1989. k = startpos;
  1990. d = (double)startpos;
  1991. part = 0.0;
  1992. if(ascatter) { /* generate random value for seg gain, within given range */
  1993. gain = drand48() * dz->param[RRR_ASCAT];
  1994. gain = 1.0 - gain;
  1995. }
  1996. if(pscatter) {
  1997. trans = (drand48() * 2.0) - 1.0;
  1998. if(trans >= 0.0) /* randomly chose up or down transposition */
  1999. trans = 1.0;
  2000. else
  2001. trans = -1.0; /* generate random semitone step within given range */
  2002. trans *= (drand48() * dz->param[RRR_PSCAT]);
  2003. trans /= 12; /* convert to transposition ratio = step in sample-reading */
  2004. trans = pow(2.0,trans);
  2005. }
  2006. while(k < endpos) {
  2007. val = ibuf[k];
  2008. nextval = ibuf[k+1];
  2009. diff = nextval - val;
  2010. z = val + (diff * part);
  2011. z *= gain;
  2012. d += trans;
  2013. k = (int)d; /* TRUNCATE */
  2014. part = d - (double)k;
  2015. obuf[outpos] = (float)z;
  2016. if(++outpos >= dz->buflen) {
  2017. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2018. return(exit_status);
  2019. outpos = 0;
  2020. }
  2021. }
  2022. } else {
  2023. for(k = startpos; k < endpos; k++) {
  2024. obuf[outpos] = ibuf[k];
  2025. if(++outpos >= dz->buflen) {
  2026. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2027. return(exit_status);
  2028. outpos = 0;
  2029. }
  2030. }
  2031. }
  2032. new_abspos = dz->total_samps_written + outpos;
  2033. if(do_slow) {
  2034. k = n % element_cnt;
  2035. gap = seg_step[k];
  2036. for(j=0;j<gap;j++) {
  2037. obuf[outpos] = 0;
  2038. if(++outpos >= dz->buflen) {
  2039. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2040. return(exit_status);
  2041. outpos = 0;
  2042. }
  2043. }
  2044. new_abspos = dz->total_samps_written + outpos;
  2045. }
  2046. abspos = new_abspos;
  2047. // If reach end of slowing curve, but still patterns left, exit pattern generation
  2048. if(dz->brksize[RRR_SLOW] && abspos >= maxsamp)
  2049. finished = 1;
  2050. // If reach end of patterns
  2051. if((total_segsection_length += seglen) >= required_segsection_len || (n == patternsize - 1)) { // Should be equivalent!!
  2052. // If not at end of slowing pattern, generate more random perms, and restart loop (n = 0)
  2053. if(dz->brksize[RRR_SLOW] && abspos < maxsamp) {
  2054. if((exit_status = rand_ints_with_restricted_repeats(element_cnt,max_elements_needed,arrsiz,fullperms,&pattern,dz)) < 0)
  2055. return(exit_status);
  2056. } else
  2057. finished = 1;
  2058. }
  2059. if(finished)
  2060. break;
  2061. }
  2062. } while(!finished);
  2063. if(!finished) {
  2064. sprintf(errstr,"Insufficient segments generated at output stage.\n");
  2065. return(PROGRAM_ERROR);
  2066. }
  2067. /* COPY SOUND END TO OUTBUF */
  2068. if(dz->vflag[1] == 0) {
  2069. for(n = pos[local_minima_cnt - 1]; n < dz->insams[0];n++) {
  2070. obuf[outpos] = ibuf[n];
  2071. if(++outpos >= dz->buflen) {
  2072. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2073. return(exit_status);
  2074. /*memset((char *)obuf,0,dz->bigbufsize);*/
  2075. memset(obuf,0,sizeof(float)* dz->buflen); /*RWD ?? */
  2076. outpos = 0;
  2077. }
  2078. }
  2079. }
  2080. if(outpos > 0) {
  2081. if((exit_status = write_samps(obuf,outpos,dz))<0)
  2082. return(exit_status);
  2083. }
  2084. return(FINISHED);
  2085. }
  2086. /****************************** RAND_INTS_WITH_RESTRICTED_REPEATS ****************************/
  2087. int rand_ints_with_restricted_repeats(int element_cnt,int max_elements_needed,int arrsiz,int fullperms,int **pattern,dataptr dz)
  2088. {
  2089. int n, m, i, k=0, j;
  2090. int endcnt, endval, allowed, checkpart;
  2091. int patterncnt = 0;
  2092. int *arr, *arr2, *perm;
  2093. if((arr = (int *)malloc(arrsiz * sizeof(int)))==NULL) {
  2094. sprintf(errstr,"Insufficient memory for permutation array 1.\n");
  2095. return(MEMORY_ERROR);
  2096. }
  2097. if((perm = (int *)malloc(arrsiz * sizeof(int)))==NULL) {
  2098. sprintf(errstr,"Insufficient memory for permutation array 2.\n");
  2099. return(MEMORY_ERROR);
  2100. }
  2101. if((arr2 = (int *)malloc(dz->iparam[RRR_REPET] * sizeof(int)))==NULL) {
  2102. sprintf(errstr,"Insufficient memory for permutation array 3.\n");
  2103. return(MEMORY_ERROR);
  2104. }
  2105. n = 0;
  2106. for(j=0;j<dz->iparam[RRR_REPET];j++) { /* fill array with REPET copies of values. */
  2107. for(i=0;i<element_cnt;i++) /* this set can be permd AS A WHOLE, as repet adjacent copies of any val */
  2108. arr[n++] = i; /* which might arise in perming this set, are allowed */
  2109. }
  2110. endcnt = 0; /* number of items repeated at end of previous perm */
  2111. endval = -1; /* value (possibly repeated) at end of previous perm (for first perm set it to a val not in perm */
  2112. /* initially this is just the 'startval' fixed by the user */
  2113. allowed = dz->iparam[RRR_REPET]; /* number of permissible repetitions of this val at start of 1st perm */
  2114. checkpart = arrsiz - dz->iparam[RRR_REPET]; /* items at end of array to test for repetitions */
  2115. n = 0;
  2116. while(n < fullperms) {
  2117. do_repet_restricted_perm(arr,perm,arrsiz,allowed,endval);
  2118. j = 0;
  2119. for(m = 0;m <arrsiz;m++) {
  2120. (*pattern)[patterncnt] = arr[perm[m]];
  2121. patterncnt++;
  2122. if(m >= checkpart) /* save last checkable stretch of perm */
  2123. arr2[j++] = arr[perm[m]];
  2124. }
  2125. if(n < fullperms -1) {
  2126. j--;
  2127. endval = arr2[j--]; /* note the val at end of perm */
  2128. endcnt = 1; /* and count it */
  2129. for(k = j; k>= 0; k--) {
  2130. if(arr2[k] == endval) /* check adjacent vals, for repetition of value: count */
  2131. endcnt++;
  2132. else /* if no more repetitions, finish counting */
  2133. break;
  2134. }
  2135. allowed = dz->iparam[RRR_REPET] - endcnt; /* get number of permissible repets at start of next perm */
  2136. }
  2137. n++;
  2138. }
  2139. return FINISHED;
  2140. }
  2141. /****************************** DO_REPET_RESTRICTED_PERM ****************************/
  2142. void do_repet_restricted_perm(int *arr, int *perm, int arrsiz, int allowed, int endval)
  2143. {
  2144. int n, t;
  2145. int checklen = allowed + 1;
  2146. int done = 0;
  2147. while(!done) {
  2148. for(n=0;n<arrsiz;n++) {
  2149. t = (int)(drand48() * (double)(n+1)); /* TRUNCATE */
  2150. if(t==n)
  2151. hhprefix(n,arrsiz,perm);
  2152. else
  2153. hhinsert(n,t,arrsiz,perm);
  2154. }
  2155. if(checklen <= 0)
  2156. break;
  2157. for(n=0;n<checklen;n++) {
  2158. if(arr[perm[n]] == endval) { /* if this is val (repeated) at end of last perm */
  2159. if(allowed == 0) /* if repetition not allowed, force a new perm val */
  2160. break;
  2161. else /* else, repetitions still allowed */
  2162. allowed--; /* decrement number of permissible further repets */
  2163. } else {
  2164. done = 1; /* if this is not val at end of last perm */
  2165. break; /* perm is OK */
  2166. }
  2167. }
  2168. }
  2169. }
  2170. /***************************** HHINSERT **********************************
  2171. *
  2172. * Insert the value m AFTER the T-th element in perm[].
  2173. */
  2174. void hhinsert(int m,int t,int setlen,int *perm)
  2175. {
  2176. hhshuflup(t+1,setlen,perm);
  2177. perm[t+1] = m;
  2178. }
  2179. /***************************** HHPREFIX ************************************
  2180. *
  2181. * Insert the value m at start of the permutation perm[].
  2182. */
  2183. void hhprefix(int m,int setlen,int *perm)
  2184. {
  2185. hhshuflup(0,setlen,perm);
  2186. perm[0] = m;
  2187. }
  2188. /****************************** HHSHUFLUP ***********************************
  2189. *
  2190. * move set members in perm[] upwards, starting from element k.
  2191. */
  2192. void hhshuflup(int k,int setlen,int *perm)
  2193. {
  2194. int n, *i;
  2195. int z = setlen - 1;
  2196. i = (perm+z);
  2197. for(n = z;n > k;n--) {
  2198. *i = *(i-1);
  2199. i--;
  2200. }
  2201. }
  2202. /****************************** ELIMINATE_SPURIOUS_MINIMA ***********************************/
  2203. int eliminate_spurious_minima(int *local_minima_cnt,int *minimum_element_len,dataptr dz)
  2204. {
  2205. int exit_status;
  2206. int *seg;
  2207. int *segpos, badseg;
  2208. int n, m, segcnt = (*local_minima_cnt) - 1, temp,eliminate_pos;
  2209. double *peak = dz->parray[0];
  2210. int *pos = dz->lparray[0];
  2211. int maxseg, minseg, minsegstartpos;
  2212. if((seg = (int *)malloc(segcnt * sizeof(int)))==NULL) {
  2213. sprintf(errstr,"Insufficient memory (A) to check for spurious local minima\n");
  2214. return(MEMORY_ERROR);
  2215. }
  2216. if((segpos = (int *)malloc(segcnt * sizeof(int)))==NULL) {
  2217. sprintf(errstr,"Insufficient memory (B) to check for spurious local minima\n");
  2218. return(MEMORY_ERROR);
  2219. }
  2220. for(;;) { /* RECURSIVELY ELIMINATE TOO-SHORT GAPS */
  2221. for(n = 0; n < segcnt; n++)
  2222. seg[n] = pos[n+1] - pos[n];
  2223. for(n = 0; n < segcnt; n++)
  2224. segpos[n] = n;
  2225. for(n=0;n < segcnt-1; n++) { /* BUBBLE SORT THE GAPS BETWEEN LOCAL MINIMA TO DESCENDING SIZE ORDER */
  2226. for(m=n+1;m < segcnt; m++) {
  2227. if(seg[n] < seg[m]) {
  2228. temp = seg[n];
  2229. seg[n] = seg[m];
  2230. seg[m] = temp;
  2231. temp = segpos[n]; /* AND KEEP TRACK OF WHERE THESE NEWLY ORDERED GAPS ARE */
  2232. segpos[n] = segpos[m];
  2233. segpos[m] = temp;
  2234. }
  2235. }
  2236. }
  2237. maxseg = seg[0];
  2238. minseg = seg[segcnt-1];
  2239. badseg = 0; /* Compare minimum seg with maximum seg */
  2240. if((double)minseg < (double)maxseg * dz->param[RRR_RANGE]) {
  2241. badseg = 1;
  2242. }
  2243. if(!badseg) { /* No more anomalous segs found, exit loop */
  2244. *minimum_element_len = minseg;
  2245. break;
  2246. }
  2247. if(segcnt-1 < 3) {
  2248. sprintf(errstr,"Insufficient valid local minima found during elimination of spurious minima. Are the search times incorrect??\n");
  2249. return(DATA_ERROR);
  2250. }
  2251. minsegstartpos = segpos[segcnt-1]; /* Find positions of minimum seg start */
  2252. if((exit_status = which_minimum_to_eliminate(minsegstartpos,pos,maxseg,segcnt,&eliminate_pos,dz)) < 0)
  2253. return(exit_status);
  2254. for(n=eliminate_pos ; n < (*local_minima_cnt)-1;n++) {
  2255. peak[n] = peak[n+1]; /* Eliminate unwanted val, by moving values in array above it down 1 position */
  2256. pos[n] = pos[n+1]; /* If BAD minimum is at current end of array, it just gets ignored as result of "local_minima_cnt--" */
  2257. }
  2258. (*local_minima_cnt)--; /* Reduce count of minima, and count of segs between minima */
  2259. segcnt--;
  2260. }
  2261. return(FINISHED);
  2262. }
  2263. /****************************** FIND_ALL_POSITIVE_PEAKS ***********************************/
  2264. int find_all_positive_peaks(int startsearch,int endsearch,int *peakcnt,dataptr dz)
  2265. {
  2266. double *peak = dz->parray[0], thispeak;
  2267. int *pos = dz->lparray[0];
  2268. float *ibuf = dz->sampbuf[0];
  2269. int thissamp = startsearch, thispos;
  2270. while(ibuf[thissamp] <= 0) { /* skip values below zero */
  2271. if(++thissamp >= endsearch)
  2272. break;
  2273. }
  2274. if(thissamp >= endsearch) {
  2275. sprintf(errstr,"Cannot locate any peaks in the signal. Are the search times incorrect??\n");
  2276. return(DATA_ERROR);
  2277. }
  2278. thispeak = ibuf[thissamp];
  2279. thispos = thissamp;
  2280. thissamp++;
  2281. while(thissamp < endsearch) {
  2282. if(ibuf[thissamp] >= 0.0) {
  2283. if(ibuf[thissamp] > thispeak) { /* search for (positive) peak val */
  2284. thispeak = ibuf[thissamp];
  2285. thispos = thissamp;
  2286. }
  2287. } else {
  2288. peak[*peakcnt] = thispeak; /* once signal becomes -ve3, store last found peak */
  2289. pos[*peakcnt] = thispos;
  2290. (*peakcnt)++;
  2291. while(ibuf[thissamp] < 0) { /* then skip over -ve part of signal */
  2292. if(++thissamp >= endsearch)
  2293. break;
  2294. }
  2295. thispeak = ibuf[thissamp]; /* once dignal is +ve again, set up an initial value for peak */
  2296. thispos = thissamp;
  2297. }
  2298. thissamp++;
  2299. }
  2300. if(*peakcnt > 0) { /* check for peak found near end, before signal goes -ve once more */
  2301. if((thispos != pos[(*peakcnt)-1]) && (thispeak > 0.0)) {
  2302. peak[*peakcnt] = thispeak;
  2303. pos[*peakcnt] = thispos;
  2304. (*peakcnt)++;
  2305. }
  2306. }
  2307. if(*peakcnt < 3) {
  2308. sprintf(errstr,"Insufficient signal peaks found. Are the search times incorrect??\n");
  2309. return(DATA_ERROR);
  2310. }
  2311. return(FINISHED);
  2312. }
  2313. /****************************** FIND_ALL_LOCAL_MINIMA ***********************************/
  2314. int find_all_local_minima(int peakcnt,int *local_minima_cnt,dataptr dz)
  2315. {
  2316. int thispeak;
  2317. double *peak = dz->parray[0];
  2318. int *pos = dz->lparray[0];
  2319. /* double peakmin = peak[0];*/
  2320. int finished = 0;
  2321. *local_minima_cnt = 0;
  2322. thispeak = 1;
  2323. while(thispeak < peakcnt) {
  2324. while(peak[thispeak] <= peak[thispeak-1]) { /* while peaks are falling, look for local peak minimum */
  2325. if(++thispeak >= peakcnt) {
  2326. finished = 1;
  2327. break;
  2328. }
  2329. }
  2330. if(finished)
  2331. break;
  2332. peak[*local_minima_cnt] = peak[thispeak-1]; /* store value and position of local mimimum */
  2333. pos[*local_minima_cnt] = pos[thispeak-1];
  2334. (*local_minima_cnt)++;
  2335. while(peak[thispeak] >= peak[thispeak-1]) { /* skip over rising sequence of peaks */
  2336. if(++thispeak >= peakcnt) {
  2337. break;
  2338. }
  2339. }
  2340. }
  2341. if(*local_minima_cnt < 3) {
  2342. sprintf(errstr,"Insufficient local minima found in inital search. Are the search times incorrect??\n");
  2343. return(DATA_ERROR);
  2344. }
  2345. return(FINISHED);
  2346. }
  2347. /****************************** LOCATE_ZERO_CROSSINGS ***********************************/
  2348. int locate_zero_crossings(int local_minima_cnt,dataptr dz)
  2349. {
  2350. int finished = 0;
  2351. int n;
  2352. float *ibuf = dz->sampbuf[0];
  2353. double *peak = dz->parray[0];
  2354. int *pos = dz->lparray[0];
  2355. for(n=0;n<local_minima_cnt;n++) {
  2356. while (peak[n] >= 0.0) { /* advance position from minimum +ve peak until value crosses zero */
  2357. if(++pos[n] >= dz->insams[0]) {
  2358. finished = 1;
  2359. if(peak[n] > 0.0) { /* if end of file does not go to zero, Warn */
  2360. fprintf(stdout,"WARNING: End_of_sound segment doesn't fall to zero level, & may cause clicks in output. (Dovetail end of sound?)\n");
  2361. fflush(stdout);
  2362. }
  2363. break;
  2364. }
  2365. peak[n] = ibuf[pos[n]];
  2366. }
  2367. if(finished)
  2368. break;
  2369. }
  2370. return(FINISHED);
  2371. }
  2372. /****************************** WHICH_MINIMUM_TO_ELIMINATE ***********************************
  2373. *
  2374. * Too short segment can be eliminated by deleting minimum at its start, or at its end.
  2375. * Eliminating the minimum will make the preceding (or following) segment larger.
  2376. * Deduce which of the two minima to delete.
  2377. */
  2378. int which_minimum_to_eliminate(int minsegstartpos,int *pos,int maxseg,int segcnt,int *eliminate_pos,dataptr dz)
  2379. {
  2380. int newpreseg, newpostseg, later_seg, prior_seg;
  2381. double ratio, ratio2, presegratio=0, postsegratio=0;
  2382. if(minsegstartpos == 0) { /* if minseg is at start of sequence */
  2383. if(pos[2] - pos[0] > maxseg) /* losing end min of seg makes next seg bigger: if bigger than maxseg, eliminate start min instead */
  2384. *eliminate_pos = minsegstartpos; /* effectively erasing the first seg */
  2385. else /* else lose end min, making following seg larger */
  2386. *eliminate_pos = minsegstartpos + 1;
  2387. } else if(minsegstartpos + 1 == segcnt) { /* if minseg is at end of sequence */
  2388. if(pos[minsegstartpos+1] - pos[minsegstartpos-1] > maxseg)
  2389. *eliminate_pos = minsegstartpos + 1; /* if losing start min of seg makes prior seg > maxseg, eliminate end min instead */
  2390. else /* else element start min, making previous seg larger */
  2391. *eliminate_pos = minsegstartpos;
  2392. /* ELSE we're not dealing with segs at ends of sequence */
  2393. } else {
  2394. newpreseg = (pos[minsegstartpos+1] - pos[minsegstartpos-1]); /* Find length new seg created by eliminating start min of shortest seg */
  2395. newpostseg = (pos[minsegstartpos+2] - pos[minsegstartpos]); /* Find length new seg created by eliminating end min of shortest seg */
  2396. if(newpreseg > maxseg || newpostseg > maxseg) { /* if either new seg is > maxseg */
  2397. if(newpostseg <= maxseg) /* If ONLY preseg inter than maxseg, choose to make postseg, elim end min */
  2398. *eliminate_pos = minsegstartpos + 1;
  2399. else if(newpreseg <= maxseg) /* If ONLY postseg > maxseg, choose to make postseg, elim start min */
  2400. *eliminate_pos = minsegstartpos;
  2401. /* else if BOTH > maxseg, choose smaller */
  2402. else if(newpreseg > newpostseg) /* if new preseg is larger, keep postseg, eliminate end min */
  2403. *eliminate_pos = minsegstartpos + 1;
  2404. else /* if new preseg is smaller, keep preseg, eliminate start min */
  2405. *eliminate_pos = minsegstartpos;
  2406. } else { /* both preseg and postseg are less than maxseg, choose seg that tallies best with local seg environment */
  2407. if(segcnt <=3) { /* with only 3 segs, any deletion affects (increases sizeof) maxseg */
  2408. /* Thus newly created seg, wherever it is, will be > sizeof orig maxseg, and will have been dealt with above */
  2409. sprintf(errstr,"Programming error xxxx.\n");
  2410. return(PROGRAM_ERROR);
  2411. }
  2412. /* find the maximum size ratio between new newpreseg and its adjacent segs */
  2413. later_seg = pos[minsegstartpos+2] - pos[minsegstartpos+1];
  2414. ratio = (double)newpreseg/(double)later_seg;
  2415. if(ratio < 1.0)
  2416. ratio = 1.0/ratio;
  2417. if(minsegstartpos - 2 > 0) {
  2418. prior_seg = pos[minsegstartpos-1] - pos[minsegstartpos-2];
  2419. ratio2 = (double)newpreseg/(double)prior_seg;
  2420. if(ratio2 < 1.0)
  2421. ratio2 = 1.0/ratio2;
  2422. ratio = max(ratio,ratio2);
  2423. }
  2424. presegratio = ratio;
  2425. /* find the maximum size ratio between new newpostseg and its adjacent segs */
  2426. ratio = 0.0;
  2427. prior_seg = pos[minsegstartpos] - pos[minsegstartpos-1];
  2428. ratio = (double)newpostseg/(double)prior_seg;
  2429. if(ratio < 1.0)
  2430. ratio = 1.0/ratio;
  2431. if(minsegstartpos + 3 < segcnt) {
  2432. later_seg = pos[minsegstartpos+3] - pos[minsegstartpos+2];
  2433. ratio2 = (double)newpostseg/(double)later_seg;
  2434. if(ratio2 < 1.0)
  2435. ratio2 = 1.0/ratio2;
  2436. ratio = max(ratio,ratio2);
  2437. }
  2438. postsegratio = ratio;
  2439. }
  2440. if(postsegratio < presegratio) /* if newpostseg makes better sense, eliminate end min */
  2441. *eliminate_pos = minsegstartpos + 1;
  2442. else /* else newporeseg makes better sense, elminate start min */
  2443. *eliminate_pos = minsegstartpos;
  2444. }
  2445. return FINISHED;
  2446. }
  2447. /****************************** ELIMINATE_EXCESS_MINIMA ***********************************
  2448. *
  2449. * If no of segments found is >> anticipated segments, Group segments together in 'best' arrangement.
  2450. */
  2451. int eliminate_excess_minima(int *local_minima_cnt,int *pos,dataptr dz)
  2452. {
  2453. int n, m, j, bestgroup = 0; /* if found-segs is exact multiple of anticipated-segs, bestgrouping starts at position 0 */
  2454. int more_than_possible = dz->insams[0]; /* i.e. too large to be reached by calculation */
  2455. int segcnt = (*local_minima_cnt) - 1; /* Number of segs found e.g. 19 */
  2456. int grouping_cnt = segcnt/dz->iparam[RRR_GET]; /* How many segs to join-as-a-group, to make no of segs tally with anticipated value */
  2457. /* if get=4 19/4 --> 4 by integer truncation */
  2458. int remnant = (int)(segcnt - (grouping_cnt * dz->iparam[RRR_GET])); /* How many segments are then spare at start or end of sequence of segs */
  2459. /* e.g. 19 - 16 = 3 */
  2460. int diff, mindiff = more_than_possible;
  2461. int grouped_len, max_grouped_len, min_grouped_len;
  2462. for(n=0;n<remnant;n++) { /* for all possible sets of consecutive segments i.e. in example 0-15, 1-16, 2-17, 3-18 */
  2463. grouped_len = 0; /* starting at 0,1,2,3 respectively */
  2464. max_grouped_len = 0;
  2465. min_grouped_len = more_than_possible;
  2466. for(m=n;m < segcnt;m+=grouping_cnt) {
  2467. for(j=0;j<grouping_cnt;j++) /* combine consecutive segs in groups of 'grouping_cnt', summing lengths */
  2468. grouped_len += pos[m+j]; /* find max and min lengths of new grouped-segments */
  2469. max_grouped_len = max(max_grouped_len,grouped_len);
  2470. min_grouped_len = min(min_grouped_len,grouped_len);
  2471. } /* Find range of the new lengths */
  2472. diff = max_grouped_len - min_grouped_len;
  2473. if(diff < mindiff)
  2474. bestgroup = n; /* look for set of grouped-segments with lowest range */
  2475. }
  2476. for(n= 0,m=bestgroup;m < *local_minima_cnt;n++,m+=grouping_cnt)
  2477. pos[n] = pos[m]; /* group orig segs by overwriting intermediate min-positions */
  2478. *local_minima_cnt = n;
  2479. return(FINISHED);
  2480. }
  2481. /************************* TIMESTRETCH_ITERATIVE2 *******************************/
  2482. int timestretch_iterative2(dataptr dz)
  2483. {
  2484. int exit_status;
  2485. /* double maxenv = 10000.0;*/
  2486. int n, m, k, rrr_cnt, rrr_start=0, peakwidth;
  2487. int *trofpnt;
  2488. int trofpntcnt = 0, lasttrofpntcnt = 0;
  2489. float lastenval;
  2490. int could_be_rrr_flap, gotrrr = 0;
  2491. int envcnt;
  2492. fprintf(stdout,"INFO: Searching file envelope.\n");
  2493. fflush(stdout);
  2494. rrr_cnt = -dz->iparam[RRR_SKIP]; /* Number of iterate units to skip before utilising any of them */
  2495. if(((envcnt = dz->insams[0]/dz->iparam[RRR_SAMP_WSIZENU]) * dz->iparam[RRR_SAMP_WSIZENU])!=dz->insams[0])
  2496. envcnt++;
  2497. if((dz->env=(float *)malloc((envcnt+20) * sizeof(float)))==NULL) {
  2498. sprintf(errstr,"INSUFFICIENT MEMORY for envelope array.\n");
  2499. return(MEMORY_ERROR);
  2500. }
  2501. if((exit_status = extract_rrr_env_from_sndfile(RRR_SAMP_WSIZENU,dz))<0)
  2502. return(exit_status);
  2503. if((trofpnt = (int *)malloc(envcnt * sizeof(int)))==NULL) {
  2504. sprintf(errstr,"INSUFFICIENT MEMORY TO ANALYSE ENVELOPE.\n");
  2505. return(MEMORY_ERROR);
  2506. }
  2507. trofpnt[0] = 0;
  2508. lastenval = dz->env[0];
  2509. n = 1;
  2510. while(n < envcnt) { /* GET FIRST ENVELOPE TROUGH */
  2511. if(dz->env[n] > lastenval) {
  2512. trofpnt[0] = 0;
  2513. lastenval = dz->env[n];
  2514. n++;
  2515. break;
  2516. } else if (dz->env[n] < lastenval) {
  2517. trofpnt[0] = n;
  2518. lastenval = dz->env[n];
  2519. n++;
  2520. break;
  2521. }
  2522. lastenval = dz->env[n];
  2523. n++;
  2524. }
  2525. if(n >= envcnt) {
  2526. sprintf(errstr,"NO PEAKS FOUND IN ENVELOPE\n");
  2527. return(GOAL_FAILED);
  2528. }
  2529. while(n < envcnt) { /* GET ENVELOPE TROUGHS */
  2530. if(dz->env[n] > lastenval) {
  2531. trofpntcnt = lasttrofpntcnt + 1;
  2532. } else if (dz->env[n] < lastenval) {
  2533. trofpnt[trofpntcnt] = n;
  2534. lasttrofpntcnt = trofpntcnt;
  2535. }
  2536. lastenval = dz->env[n];
  2537. n++;
  2538. }
  2539. if(trofpntcnt < 2) {
  2540. sprintf(errstr,"NO SIGNIFICANT PEAKS FOUND IN ENVELOPE\n");
  2541. return(GOAL_FAILED);
  2542. }
  2543. for(m = 0, n=1;n<trofpntcnt;m++,n++) {
  2544. peakwidth = trofpnt[n] - trofpnt[m];
  2545. if(peakwidth > 2 && peakwidth < 6) { /* IF PEAK WIDTH IS WITHIN LIMITS FOR AN ITERATE-UNIT */
  2546. could_be_rrr_flap = 0;
  2547. for(k = trofpnt[m]; k < trofpnt[n]; k++) { /* AND PEAK IS ABOVE GATE */
  2548. if(dz->env[k] > dz->param[RRR_GATE]) {
  2549. could_be_rrr_flap = 1;
  2550. break;
  2551. }
  2552. }
  2553. if(could_be_rrr_flap) {
  2554. if(rrr_cnt == 0) /* IF (skipped unwanted flaps &) NO FLAPS HERE YET */
  2555. rrr_start = m; /* MARK START OF A POSSIBLE FLAP */
  2556. rrr_cnt++; /* COUNT FLAPS */
  2557. }
  2558. } else {
  2559. could_be_rrr_flap = 0; /* MARK NON-FLAP */
  2560. }
  2561. if (!could_be_rrr_flap) {
  2562. if(rrr_cnt >= dz->iparam[RRR_GET]) { /* IF END OF FLAPS, AND WE HAVE ENOUGH ADJACENT FLAPS */
  2563. /* SET PARAMS FOR ZER-CROSSING SEARCH */
  2564. dz->iparam[RRR_START] = trofpnt[rrr_start] * dz->iparam[RRR_SAMP_WSIZENU];
  2565. dz->iparam[RRR_START] -= dz->iparam[RRR_SAMP_WSIZENU]/ 2; /* Start search before first flap segment */
  2566. dz->iparam[RRR_START] = max(0,dz->iparam[RRR_START]);
  2567. dz->iparam[RRR_END] = trofpnt[m] * dz->iparam[RRR_SAMP_WSIZENU];;
  2568. dz->iparam[RRR_END] += dz->iparam[RRR_SAMP_WSIZENU]/ 2; /* End search after last flap segment */
  2569. dz->iparam[RRR_END] = min(dz->insams[0],dz->iparam[RRR_END]);
  2570. dz->param[RRR_START] = (double)dz->iparam[RRR_START]/dz->infile->srate;
  2571. dz->param[RRR_END] = (double)dz->iparam[RRR_END]/dz->infile->srate;
  2572. // dz->iparam[RRR_GET] = rrr_cnt;
  2573. // EXPERIMENTAL!! FORCES zero-cross algo to get better result
  2574. // if algo finds 8 zcs and there are really rrr_cnt=4, as 8 >= 2 * 4 , it groups the zcs in pairs to give 4 zcs
  2575. // However, if algo finds 7 zcs and there are really rrr_cnt=4
  2576. // 7 < (2*4), so it doesn't group the zcs in twos, so 7 zcs are kept, probalby too many...
  2577. // With this mod 7 > 2*(rrr_cnt-1 = 3) so it groups the number of zcs in 2s (and throws 1 away) to give 3 zcs: better result
  2578. dz->iparam[RRR_GET] = rrr_cnt - 1;
  2579. gotrrr = 1;
  2580. break;
  2581. } else {
  2582. rrr_cnt = -dz->iparam[RRR_SKIP];
  2583. }
  2584. }
  2585. }
  2586. if(gotrrr == 0) {
  2587. sprintf(errstr,"NO ITERATIVE LOCATION FOUND\n");
  2588. return(GOAL_FAILED);
  2589. } else {
  2590. fprintf(stdout,"INFO: searching between %.04lf and %.04lf secs: where %d peaks found\n",dz->param[RRR_START],dz->param[RRR_END],rrr_cnt);
  2591. fflush(stdout);
  2592. }
  2593. return timestretch_iterative(dz);
  2594. }
  2595. /************************* EXTRACT_RRR_ENV_FROM_SNDFILE *******************************/
  2596. int extract_rrr_env_from_sndfile(int paramno,dataptr dz)
  2597. {
  2598. int n;
  2599. float *envptr;
  2600. int bufcnt;
  2601. if(((bufcnt = dz->insams[0]/dz->buflen)*dz->buflen)!=dz->insams[0])
  2602. bufcnt++;
  2603. envptr = dz->env;
  2604. for(n = 0; n < bufcnt; n++) {
  2605. if((dz->ssampsread = fgetfbufEx(dz->sampbuf[0], dz->buflen,dz->ifd[0],0)) < 0) {
  2606. sprintf(errstr,"Can't read samples from soundfile: extract_rrr_env_from_sndfile()\n");
  2607. return(SYSTEM_ERROR);
  2608. }
  2609. if(sloom)
  2610. display_virtual_time(dz->total_samps_read,dz);
  2611. get_rrrenv_of_buffer(dz->ssampsread,dz->iparam[paramno],&envptr,dz->sampbuf[0]);
  2612. }
  2613. dz->envend = envptr;
  2614. return(FINISHED);
  2615. }
  2616. /************************* GET_RRRENV_OF_BUFFER *******************************/
  2617. void get_rrrenv_of_buffer(int samps_to_process,int envwindow_sampsize,float **envptr,float *buffer)
  2618. {
  2619. int start_samp = 0;
  2620. float *env = *envptr;
  2621. while(samps_to_process >= envwindow_sampsize) {
  2622. *env++ = getmaxsampr(start_samp,envwindow_sampsize,buffer);
  2623. start_samp += envwindow_sampsize;
  2624. samps_to_process -= envwindow_sampsize;
  2625. }
  2626. if(samps_to_process) /* Handle any final short buffer */
  2627. *env++ = getmaxsampr(start_samp,samps_to_process,buffer);
  2628. *envptr = env;
  2629. }
  2630. /*************************** GETMAXSAMPR ******************************/
  2631. float getmaxsampr(int startsamp, int sampcnt,float *buffer)
  2632. {
  2633. int i, endsamp = startsamp + sampcnt;
  2634. float thisval, thismaxsamp = 0.0f;
  2635. for(i = startsamp; i<endsamp; i++) {
  2636. if((thisval = (float)fabs(buffer[i]))>thismaxsamp)
  2637. thismaxsamp = thisval;
  2638. }
  2639. return(thismaxsamp);
  2640. }
  2641. /********************************** GRAB_NOISE_AND_EXPAND **********************************
  2642. *
  2643. * Locate noise, then expand it by random-reads from zero-cross to zero-cross
  2644. */
  2645. int grab_noise_and_expand(dataptr dz)
  2646. {
  2647. int exit_status;
  2648. float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1];
  2649. int phase, initialphase, isnoise = -1, finished = 0;
  2650. int j, k, n, m, waveset_cnt;
  2651. int lastzcross = 0, sampstart, sampend, len, temp, orig_buflen;
  2652. int brkpntcnt = 0, got_noise = 0;
  2653. double maxsamp, gate = dz->param[SSS_GATE];
  2654. int abovegate = 0;
  2655. if((dz->lparray[0] = (int *)malloc(dz->insams[0] * sizeof(int)))==NULL) {
  2656. sprintf(errstr,"INSUFFICIENT MEMORY.\n");
  2657. return(DATA_ERROR);
  2658. }
  2659. fprintf(stdout,"INFO: Searching for noise.\n");
  2660. fflush(stdout);
  2661. orig_buflen = dz->buflen;
  2662. dz->buflen = dz->insams[0];
  2663. if((exit_status = read_samps(ibuf,dz))<0)
  2664. return(exit_status);
  2665. else if(dz->ssampsread <= 0) {
  2666. sprintf(errstr,"Failed to read sound from input file\n");
  2667. return(DATA_ERROR);
  2668. }
  2669. dz->buflen = orig_buflen;
  2670. /* ESTABLISH INITIAL PHASE OF SIGNAL */
  2671. n = 0;
  2672. while(ibuf[n]==0) {
  2673. if(++n >= dz->ssampsread) {
  2674. sprintf(errstr,"FAILED TO FIND ANY WAVECYCLES IN FILE.\n");
  2675. return(DATA_ERROR);
  2676. }
  2677. }
  2678. if(ibuf[n] > 0)
  2679. initialphase = 1;
  2680. else
  2681. initialphase = -1;
  2682. for(;;) {
  2683. /* FIND A WAVECYCLE */
  2684. maxsamp = 0.0;
  2685. if(initialphase == 1) {
  2686. while(ibuf[n] > 0) {
  2687. maxsamp = max(maxsamp,ibuf[n]);
  2688. if(++n >= dz->ssampsread) {
  2689. finished = 1;
  2690. break;
  2691. }
  2692. }
  2693. while(ibuf[n] <= 0) {
  2694. maxsamp = max(maxsamp,-ibuf[n]);
  2695. if(++n >= dz->ssampsread) {
  2696. finished = 1;
  2697. break;
  2698. }
  2699. }
  2700. } else {
  2701. while(ibuf[n] < 0) {
  2702. maxsamp = max(maxsamp,-ibuf[n]);
  2703. if(++n >= dz->ssampsread) {
  2704. finished = 1;
  2705. break;
  2706. }
  2707. }
  2708. while(ibuf[n] >= 0) {
  2709. maxsamp = max(maxsamp,ibuf[n]);
  2710. if(++n >= dz->ssampsread) {
  2711. finished = 1;
  2712. break;
  2713. }
  2714. }
  2715. }
  2716. if(finished)
  2717. break;
  2718. if(maxsamp < gate)
  2719. isnoise = 0;
  2720. else {
  2721. abovegate = 1;
  2722. dz->lparray[0][brkpntcnt] = n;
  2723. /* MEASURE WAVE-CYCLE LENGTH, AND TEST FOR NOISE */
  2724. /* IF SIGNAL SWITCHES FROM NOISE to NOT-NOISE or vice versa, STORE THAT POSITION */
  2725. if(dz->lparray[0][brkpntcnt] - lastzcross < dz->iparam[NOISE_MINFRQ]) {
  2726. if(brkpntcnt == 0) /* if noise-start pos, move to search for noise-end position */
  2727. brkpntcnt = 1;
  2728. else if(dz->lparray[0][1] - dz->lparray[0][0] >= dz->iparam[MAX_NOISLEN]) {
  2729. got_noise = 1;
  2730. break;
  2731. }
  2732. isnoise = 1;
  2733. } else {
  2734. if(isnoise == 1) { /* if at end of noise ... */
  2735. /* if enough noise present ... break */
  2736. if(dz->lparray[0][1] - dz->lparray[0][0] > dz->iparam[MIN_NOISLEN]) {
  2737. got_noise = 1;
  2738. break;
  2739. } else { /* if NOT ENOUGH noise present, delete noise pos data, start again */
  2740. dz->lparray[0][0] = dz->lparray[0][1];
  2741. brkpntcnt = 0;
  2742. }
  2743. }
  2744. isnoise = 0;
  2745. }
  2746. }
  2747. lastzcross = n; /* store position of last waveset end... */
  2748. }
  2749. /* CHECK THAT ANY NOISE : non-NOISE SWITCHES FOUND */
  2750. if(!abovegate) {
  2751. sprintf(errstr,"NO SIGNAL IS ABOVE THE GATE LEVEL\n");
  2752. return(GOAL_FAILED);
  2753. }
  2754. if(!got_noise) {
  2755. if(gate > 0)
  2756. sprintf(errstr,"NO NOISE FOUND WITH GATE-LEVEL %lf\n",gate);
  2757. else
  2758. sprintf(errstr,"NO NOISE FOUND\n");
  2759. return(GOAL_FAILED);
  2760. }
  2761. fprintf(stdout,"INFO: Generating output.\n");
  2762. fflush(stdout);
  2763. sampstart = dz->lparray[0][0];
  2764. sampend = dz->lparray[0][1];
  2765. waveset_cnt = 0;
  2766. if(ibuf[sampstart] > 0) {
  2767. initialphase = 1;
  2768. phase = 1;
  2769. dz->lparray[0][waveset_cnt++] = sampstart;
  2770. } else if (ibuf[sampstart] < 0) {
  2771. initialphase = -1;
  2772. phase = -1;
  2773. dz->lparray[0][waveset_cnt++] = sampstart;
  2774. } else
  2775. phase = 0;
  2776. /* STORE ZERO-CROSS-PAIR POSITIONS */
  2777. for(n = sampstart+1;n < sampend; n++) {
  2778. switch(phase) {
  2779. case(0):
  2780. if(ibuf[n] > 0) {
  2781. phase = 1;
  2782. initialphase = 1;
  2783. dz->lparray[0][waveset_cnt++] = n;
  2784. } else if(ibuf[n] < 0) {
  2785. phase = -1;
  2786. initialphase = -1;
  2787. dz->lparray[0][waveset_cnt++] = n;
  2788. }
  2789. break;
  2790. case(1):
  2791. if(ibuf[n] < 0) {
  2792. if(initialphase == -1)
  2793. dz->lparray[0][waveset_cnt++] = n;
  2794. phase = -1;
  2795. }
  2796. break;
  2797. case(-1):
  2798. if(ibuf[n] > 0) {
  2799. if(initialphase == 1)
  2800. dz->lparray[0][waveset_cnt++] = n;
  2801. phase = 1;
  2802. }
  2803. break;
  2804. }
  2805. }
  2806. j = 0;
  2807. if(!dz->vflag[0]) {
  2808. for(n=0;n<sampstart;n++) {
  2809. obuf[j++] = ibuf[n];
  2810. if(j >= dz->buflen) {
  2811. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2812. return(exit_status);
  2813. j = 0;
  2814. }
  2815. }
  2816. }
  2817. for(;;) {
  2818. n = (int)floor(drand48() * waveset_cnt); /* RANDOM READS TO AND FROM ZERO-CROSSINGS */
  2819. do {
  2820. m = (int)floor(drand48() * waveset_cnt);
  2821. } while (m == n);
  2822. if((len = dz->lparray[0][m] - dz->lparray[0][n]) < 0) {
  2823. temp = m;
  2824. m = n;
  2825. n = temp;
  2826. len = -len;
  2827. }
  2828. if(j + len >= dz->iparam[SSS_DUR]) /* HALT AT A ZERO CROSSING */
  2829. break;
  2830. for(k= dz->lparray[0][n]; k < dz->lparray[0][m];k++) {
  2831. obuf[j++] = ibuf[k];
  2832. if(j >= dz->buflen) {
  2833. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2834. return(exit_status);
  2835. dz->iparam[SSS_DUR] -= dz->buflen;
  2836. j = 0;
  2837. }
  2838. }
  2839. }
  2840. if(!dz->vflag[0]) {
  2841. for(n=sampend;n<dz->insams[0];n++) {
  2842. obuf[j++] = ibuf[n];
  2843. if(j >= dz->buflen) {
  2844. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2845. return(exit_status);
  2846. j = 0;
  2847. }
  2848. }
  2849. }
  2850. if(j > 0) {
  2851. if((exit_status = write_samps(obuf,j,dz))<0)
  2852. return(exit_status);
  2853. }
  2854. return(FINISHED);
  2855. }
  2856. /************************** GREV **********************/
  2857. int grev(dataptr dz)
  2858. {
  2859. int exit_status, finished, start_negative;
  2860. int n, j=0, k, minpeakloc, envcnt, last_total_samps_read, startsearch, endsearch, obufpos;
  2861. int lastobufpos, step, expansion, lastgrainlen=0, nu_gp_dur;
  2862. double maxsamp0, maxsamp1, peakav, minpeakav, time;
  2863. int firsttrof, up, gotmaxsamp0, crossed_zero_to_positive, crossed_zero_to_negative, gp=0, read_brk = 0;
  2864. float *e, *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1];
  2865. int *pa;
  2866. double convertor = 1.0 / dz->infile->srate;
  2867. if(((envcnt = dz->insams[0]/dz->iparam[GREV_SAMP_WSIZE]) * dz->iparam[GREV_SAMP_WSIZE])!=dz->insams[0])
  2868. envcnt++;
  2869. if((dz->env=(float *)malloc((envcnt + 12) * sizeof(float)))==NULL) {
  2870. sprintf(errstr,"INSUFFICIENT MEMORY for envelope array.\n");
  2871. return(MEMORY_ERROR);
  2872. }
  2873. e = dz->env;
  2874. if((pa =(int *)malloc((envcnt + 12) * sizeof(int)))==NULL) {
  2875. sprintf(errstr,"INSUFFICIENT MEMORY for peak positions array.\n");
  2876. return(MEMORY_ERROR);
  2877. }
  2878. if((exit_status = extract_rrr_env_from_sndfile(GREV_SAMP_WSIZE,dz))<0) /* Get envel of whole sound */
  2879. return(exit_status);
  2880. dz->total_samps_read = 0;
  2881. display_virtual_time(0,dz);
  2882. envcnt = dz->envend - dz->env;
  2883. n = 0;
  2884. k = 0;
  2885. pa[k++] = 0;
  2886. while(flteq(e[n],e[0])) {
  2887. n++;
  2888. if(n >= envcnt) {
  2889. sprintf(errstr,"NO PEAKS IN THE FILE\n");
  2890. return(GOAL_FAILED);
  2891. }
  2892. }
  2893. if(e[n] < e[0]) {
  2894. firsttrof = 1;
  2895. up = -1;
  2896. } else {
  2897. firsttrof = 0;
  2898. up = 1;
  2899. }
  2900. /* KEEP ONLY THE PEAKS AND TROUGHS OF THE ENVELOPE, AND THEIR LOCATIONS */
  2901. while (n <envcnt) { /* store peaks and troughs only */
  2902. switch(up) {
  2903. case(1):
  2904. if(e[n] < e[n-1]) {
  2905. dz->env[k] = dz->env[n-1];
  2906. pa[k] = (n-1) * dz->iparam[GREV_SAMP_WSIZE];
  2907. k++;
  2908. up = -1;
  2909. }
  2910. break;
  2911. case(-1):
  2912. if(e[n] > e[n-1]) {
  2913. dz->env[k] = dz->env[n-1];
  2914. pa[k] = (n-1) * dz->iparam[GREV_SAMP_WSIZE];
  2915. k++;
  2916. up = 1;
  2917. }
  2918. break;
  2919. }
  2920. n++;
  2921. }
  2922. if((envcnt = k) <= 3) {
  2923. sprintf(errstr,"INSUFFICIENT PEAKS IN THE FILE.\n");
  2924. return(GOAL_FAILED);
  2925. }
  2926. /* KEEP ONLY THE (DEEP ENOUGH) TROUGHS OF THE ENVELOPE */
  2927. switch(firsttrof) {
  2928. case(0): /* if trof at start */
  2929. k = 1; /* set item at 0 NOT to be overwritten (as it is first trof) (set k=1) */
  2930. j = 1; /* search for good trofs between peaks, from (j=)1 */
  2931. break;
  2932. case(1): /* if trof not at start */
  2933. k = 0; /* set item at 0 to be overwritten by 1st trof found (k=0) */
  2934. j = 0; /* search for good trofs between peaks, from (j=)0 */
  2935. break;
  2936. }
  2937. for(n=j;n<envcnt-2;n++) {
  2938. peakav = dz->env[n] + dz->env[n+2];
  2939. if(peakav * dz->param[GREV_TROFRAC] >= dz->env[n+1]) { /* NB TROF_FAC alreday PRE-MULTIPLIED by 2.0 */
  2940. pa[k] = pa[n+1];
  2941. k++;
  2942. }
  2943. }
  2944. if((envcnt = k) <= 3) {
  2945. sprintf(errstr,"INSUFFICIENT VALID TROUGHS IN THE FILE.\n");
  2946. return(GOAL_FAILED);
  2947. }
  2948. /* SEARCH WAVEFORM FOR ZERO_CROSSING AT MORE ACCURATE TROUGH */
  2949. fprintf(stdout,"INFO: Number of grains found = %d\n",envcnt);
  2950. fflush(stdout);
  2951. if((sndseekEx(dz->ifd[0],0,0))<0) {
  2952. sprintf(errstr,"seek error 1\n");
  2953. return(SYSTEM_ERROR);
  2954. }
  2955. last_total_samps_read = 0;
  2956. k = (int)round((double)dz->iparam[GREV_SAMP_WSIZE] * 0.5); /* search around size of envel window */
  2957. startsearch = max(pa[0] - k, 0);
  2958. endsearch = min(pa[0] + k,dz->insams[0]);
  2959. dz->total_samps_read = 0;
  2960. while(startsearch > dz->buflen) {
  2961. dz->total_samps_read += dz->buflen;
  2962. startsearch -= dz->buflen;
  2963. }
  2964. if(dz->total_samps_read > 0) {
  2965. if((sndseekEx(dz->ifd[0],dz->total_samps_read,0))<0) {
  2966. sprintf(errstr,"seek error 2\n");
  2967. return(SYSTEM_ERROR);
  2968. }
  2969. last_total_samps_read = dz->total_samps_read;
  2970. endsearch -= last_total_samps_read;
  2971. }
  2972. if((exit_status = read_samps(ibuf,dz))<0)
  2973. return(exit_status);
  2974. n = 0;
  2975. finished = 0;
  2976. while(n<envcnt) {
  2977. maxsamp0 = 0.0;
  2978. maxsamp1 = 0.0;
  2979. gotmaxsamp0 = 0;
  2980. minpeakav = HUGE;
  2981. minpeakloc = -1;
  2982. j = startsearch;
  2983. crossed_zero_to_positive = 0;
  2984. crossed_zero_to_negative = 0;
  2985. if(ibuf[j] <= 0)
  2986. start_negative = 1;
  2987. else
  2988. start_negative = 0;
  2989. do {
  2990. if(j >= dz->ssampsread) {
  2991. last_total_samps_read = dz->total_samps_read;
  2992. endsearch -= dz->buflen;
  2993. j -= dz->buflen;
  2994. if((exit_status = read_samps(ibuf,dz))<0)
  2995. return(exit_status);
  2996. if(dz->ssampsread == 0) {
  2997. finished = 1;
  2998. break;
  2999. }
  3000. }
  3001. if(!crossed_zero_to_negative) { /* before signal crosses to negative */
  3002. if(start_negative) {
  3003. if(ibuf[j] <= 0.0) {
  3004. j++;
  3005. continue;
  3006. }
  3007. start_negative = 0;
  3008. }
  3009. if(!gotmaxsamp0) { /* First time only, look for first maxsamp */
  3010. if(ibuf[j] > maxsamp0) /* (after first time, it gets val passed back from 2nd maxsamp */
  3011. maxsamp0 = ibuf[j];
  3012. }
  3013. if (ibuf[j] < 0.0) { /* if not crossed zero to -ve, look for, and mark, zero-cross to -ve */
  3014. crossed_zero_to_negative = j + last_total_samps_read;
  3015. gotmaxsamp0 = 1;
  3016. }
  3017. } else if (ibuf[j] >= 0) { /* if crossed zero to neg and we're now crossing back to +ve */
  3018. crossed_zero_to_positive = 1;
  3019. if(ibuf[j] > maxsamp1) /* look for 2nd maxsamp */
  3020. maxsamp1 = ibuf[j];
  3021. } else if (crossed_zero_to_positive) { /* having crossed from -ve to +ve, we're now -ve again, in a new cycle */
  3022. if((peakav = maxsamp0 + maxsamp1) < minpeakav) {
  3023. minpeakav = peakav;
  3024. minpeakloc = crossed_zero_to_negative;
  3025. }
  3026. maxsamp0 = maxsamp1;
  3027. crossed_zero_to_positive = 0;
  3028. crossed_zero_to_negative = 0;
  3029. }
  3030. j++;
  3031. } while(j < endsearch || minpeakloc < 0);
  3032. if(minpeakloc < 0) {
  3033. if (finished) { /* deal with endcases where waveform fails to cross zero (twice) */
  3034. if(crossed_zero_to_negative > 0)
  3035. pa[n++] = crossed_zero_to_negative;
  3036. envcnt = n;
  3037. break;
  3038. } else {
  3039. sprintf(errstr,"FAILED TO FIND ONE OF THE LOCAL MINIMA.\n");
  3040. return(PROGRAM_ERROR);
  3041. }
  3042. }
  3043. pa[n] = minpeakloc;
  3044. n++;
  3045. startsearch = max(pa[n] - k, 0);
  3046. endsearch = min(pa[n] + k,dz->insams[0]);
  3047. if(startsearch >= dz->total_samps_read) {
  3048. while(startsearch >= dz->total_samps_read) {
  3049. last_total_samps_read = dz->total_samps_read;
  3050. if((exit_status = read_samps(ibuf,dz))<0)
  3051. return(exit_status);
  3052. if(last_total_samps_read >= dz->total_samps_read) {
  3053. envcnt = n;
  3054. break;
  3055. }
  3056. }
  3057. }
  3058. startsearch -= last_total_samps_read;
  3059. endsearch -= last_total_samps_read;
  3060. while(startsearch < 0) { /* very tiny windows may cause backtracking in file */
  3061. last_total_samps_read -= dz->buflen;
  3062. if((sndseekEx(dz->ifd[0],last_total_samps_read,0))<0) {
  3063. sprintf(errstr,"seek error 3\n");
  3064. return(SYSTEM_ERROR);
  3065. }
  3066. if((exit_status = read_samps(ibuf,dz))<0)
  3067. return(exit_status);
  3068. dz->total_samps_read = last_total_samps_read + dz->ssampsread;
  3069. startsearch += dz->buflen;
  3070. endsearch += dz->buflen;
  3071. }
  3072. }
  3073. if((sndseekEx(dz->ifd[0],0,0))<0) {
  3074. sprintf(errstr,"seek error 4\n");
  3075. return(SYSTEM_ERROR);
  3076. }
  3077. dz->total_samps_read = 0;
  3078. last_total_samps_read = 1; /* Value 1 forces first seek and read */
  3079. obufpos = 0;
  3080. switch(dz->mode) {
  3081. case(GREV_REVERSE):
  3082. if(!dz->brksize[GREV_GPCNT])
  3083. gp = dz->iparam[GREV_GPCNT];
  3084. for(n = envcnt - (2 * gp); n>0; n-=gp) {
  3085. startsearch = pa[n];
  3086. if(dz->brksize[GREV_GPCNT]) {
  3087. time = (double)startsearch * convertor;
  3088. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  3089. return(exit_status);
  3090. gp = (int)round(dz->param[GREV_GPCNT]);
  3091. }
  3092. endsearch = pa[n + gp];
  3093. if((exit_status = do_envgrain_write(startsearch,endsearch,&last_total_samps_read,&obufpos,dz))<0)
  3094. return(exit_status);
  3095. }
  3096. break;
  3097. case(GREV_REPEAT):
  3098. if(!dz->brksize[GREV_GPCNT])
  3099. gp = dz->iparam[GREV_GPCNT];
  3100. if(dz->brksize[GREV_REPETS] || dz->brksize[GREV_GPCNT])
  3101. read_brk = 1;
  3102. for(n = 0; n<=(envcnt-gp); n+=gp) {
  3103. startsearch = pa[n];
  3104. if(read_brk) {
  3105. time = (double)startsearch * convertor;
  3106. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  3107. return(exit_status);
  3108. }
  3109. if(dz->brksize[GREV_GPCNT])
  3110. gp = (int)round(dz->param[GREV_GPCNT]);
  3111. if(dz->brksize[GREV_REPETS])
  3112. dz->iparam[GREV_REPETS] = (int)round(dz->param[GREV_REPETS]);
  3113. endsearch = pa[n + gp];
  3114. for(k = 0;k < dz->iparam[GREV_REPETS];k++) {
  3115. if((exit_status = do_envgrain_write(startsearch,endsearch,&last_total_samps_read,&obufpos,dz))<0)
  3116. return(exit_status);
  3117. }
  3118. }
  3119. break;
  3120. case(GREV_DELETE):
  3121. if(!dz->brksize[GREV_GPCNT])
  3122. gp = dz->iparam[GREV_GPCNT];
  3123. if(dz->brksize[GREV_KEEP] || dz->brksize[GREV_GPCNT])
  3124. read_brk = 1;
  3125. for(n = 0; n<=(envcnt-gp); n+=gp) {
  3126. startsearch = pa[n];
  3127. if(read_brk) {
  3128. time = (double)startsearch * convertor;
  3129. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  3130. return(exit_status);
  3131. }
  3132. if(dz->brksize[GREV_GPCNT])
  3133. gp = (int)round(dz->param[GREV_GPCNT]);
  3134. if(dz->brksize[GREV_KEEP])
  3135. dz->iparam[GREV_KEEP] = (int)round(dz->param[GREV_KEEP]);
  3136. endsearch = pa[n + gp];
  3137. if((n % dz->iparam[GREV_OUTOF]) < dz->iparam[GREV_KEEP]) {
  3138. if((exit_status = do_envgrain_write(startsearch,endsearch,&last_total_samps_read,&obufpos,dz))<0)
  3139. return(exit_status);
  3140. }
  3141. }
  3142. break;
  3143. case(GREV_OMIT):
  3144. if(!dz->brksize[GREV_GPCNT])
  3145. gp = dz->iparam[GREV_GPCNT];
  3146. if(dz->brksize[GREV_KEEP] || dz->brksize[GREV_GPCNT])
  3147. read_brk = 1;
  3148. for(n = 0; n<=(envcnt-gp); n+=gp) {
  3149. startsearch = pa[n];
  3150. if(read_brk) {
  3151. time = (double)startsearch * convertor;
  3152. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  3153. return(exit_status);
  3154. }
  3155. if(dz->brksize[GREV_GPCNT])
  3156. gp = (int)round(dz->param[GREV_GPCNT]);
  3157. if(dz->brksize[GREV_KEEP])
  3158. dz->iparam[GREV_KEEP] = (int)round(dz->param[GREV_KEEP]);
  3159. endsearch = pa[n + gp];
  3160. if((n % dz->iparam[GREV_OUTOF]) < dz->iparam[GREV_KEEP]) {
  3161. if((exit_status = do_envgrain_write(startsearch,endsearch,&last_total_samps_read,&obufpos,dz))<0)
  3162. return(exit_status);
  3163. } else {
  3164. if((exit_status = do_envgrain_zerowrite(startsearch,endsearch,&obufpos,dz))<0)
  3165. return(exit_status);
  3166. }
  3167. }
  3168. break;
  3169. case(GREV_TSTRETCH):
  3170. if(!dz->brksize[GREV_GPCNT])
  3171. gp = dz->iparam[GREV_GPCNT];
  3172. if(dz->brksize[GREV_TSTR] || dz->brksize[GREV_GPCNT])
  3173. read_brk = 1;
  3174. for(n = 0; n<=envcnt-1; n++) {
  3175. startsearch = pa[n];
  3176. if(read_brk) {
  3177. time = (double)startsearch * convertor;
  3178. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  3179. return(exit_status);
  3180. }
  3181. if(dz->brksize[GREV_GPCNT])
  3182. gp = (int)round(dz->param[GREV_GPCNT]);
  3183. endsearch = pa[n + 1];
  3184. lastobufpos = obufpos + dz->total_samps_written;
  3185. if((exit_status = do_envgrain_addwrite(startsearch,endsearch,&last_total_samps_read,&obufpos,dz))<0)
  3186. return(exit_status);
  3187. step = obufpos + dz->total_samps_written - lastobufpos;
  3188. expansion = (int)round((double)step * dz->param[GREV_TSTR]) - step;
  3189. if(expansion > 0) {
  3190. if((exit_status = do_envgrain_zerowrite_dblbuf(0,expansion,&obufpos,dz))<0)
  3191. return(exit_status);
  3192. } else
  3193. obufpos += expansion;
  3194. }
  3195. break;
  3196. case(GREV_GET):
  3197. if(!dz->brksize[GREV_GPCNT])
  3198. gp = dz->iparam[GREV_GPCNT];
  3199. else
  3200. read_brk = 1;
  3201. for(n = 0; n<=(envcnt-gp); n+=gp) {
  3202. startsearch = pa[n];
  3203. if(read_brk) {
  3204. time = (double)startsearch * convertor;
  3205. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  3206. return(exit_status);
  3207. }
  3208. if(dz->brksize[GREV_GPCNT])
  3209. gp = (int)round(dz->param[GREV_GPCNT]);
  3210. fprintf(dz->fp,"%d\n",startsearch);
  3211. }
  3212. break;
  3213. case(GREV_PUT):
  3214. if(!dz->brksize[GREV_GPCNT])
  3215. gp = dz->iparam[GREV_GPCNT];
  3216. else
  3217. read_brk = 1;
  3218. for(n = 0; n<=(envcnt-gp); n+=gp) {
  3219. startsearch = pa[n];
  3220. if(read_brk) {
  3221. time = (double)startsearch * convertor;
  3222. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  3223. return(exit_status);
  3224. }
  3225. if(dz->brksize[GREV_GPCNT])
  3226. gp = (int)round(dz->param[GREV_GPCNT]);
  3227. endsearch = pa[n + gp];
  3228. if(n > 0) {
  3229. if(n >= dz->itemcnt)
  3230. break;
  3231. nu_gp_dur = (int)round(dz->parray[GR_SYNCTIME][n] - dz->parray[GR_SYNCTIME][n-1]);
  3232. obufpos += (nu_gp_dur - lastgrainlen);
  3233. if(obufpos <= -dz->buflen) {
  3234. sprintf(errstr,"BACKTRACK TOO LARGE\n");
  3235. return(GOAL_FAILED);
  3236. }
  3237. }
  3238. if((exit_status = do_envgrain_write(startsearch,endsearch,&last_total_samps_read,&obufpos,dz))<0)
  3239. return(exit_status);
  3240. lastgrainlen = endsearch - startsearch;
  3241. }
  3242. break;
  3243. }
  3244. if(obufpos > 0) {
  3245. if((exit_status = write_samps(obuf,obufpos,dz))<0)
  3246. return(exit_status);
  3247. }
  3248. return(FINISHED);
  3249. }
  3250. /************************** DO_ENVGRAIN_WRITE **********************/
  3251. int do_envgrain_write(int startsearch,int endsearch,int *last_total_samps_read,int *obufpos,dataptr dz)
  3252. {
  3253. int exit_status;
  3254. int step, n, m, limit = dz->buflen;
  3255. float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1];
  3256. if(startsearch > dz->total_samps_read || startsearch < *last_total_samps_read) {
  3257. step = (startsearch / dz->buflen) * dz->buflen;
  3258. if((sndseekEx(dz->ifd[0],step,0))<0) {
  3259. sprintf(errstr,"seek error 5\n");
  3260. return(SYSTEM_ERROR);
  3261. }
  3262. *last_total_samps_read = step;
  3263. if((exit_status = read_samps(ibuf,dz))<0)
  3264. return(exit_status);
  3265. dz->total_samps_read = *last_total_samps_read + dz->ssampsread;
  3266. }
  3267. startsearch -= *last_total_samps_read;
  3268. endsearch -= *last_total_samps_read;
  3269. m = *obufpos;
  3270. if(dz->mode == GREV_PUT) {
  3271. limit *= 2;
  3272. while(m >= limit) {
  3273. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  3274. return(exit_status);
  3275. memcpy((char *)dz->sampbuf[1],(char *)dz->sampbuf[2],dz->buflen * sizeof(float));
  3276. memset((char *)dz->sampbuf[2],0,dz->buflen * sizeof(float));
  3277. m -= dz->buflen;
  3278. }
  3279. }
  3280. for(n=startsearch;n <endsearch;n++) {
  3281. if(n >= dz->buflen) {
  3282. *last_total_samps_read = dz->total_samps_read;
  3283. if((exit_status = read_samps(ibuf,dz))<0)
  3284. return(exit_status);
  3285. n = 0;
  3286. endsearch -= dz->buflen;
  3287. }
  3288. obuf[m++] = ibuf[n];
  3289. if(m >= limit) {
  3290. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  3291. return(exit_status);
  3292. if(dz->mode == GREV_PUT) { /* deals with bufptr < 0 */
  3293. memcpy((char *)dz->sampbuf[1],(char *)dz->sampbuf[2],dz->buflen * sizeof(float));
  3294. memset((char *)dz->sampbuf[2],0,dz->buflen * sizeof(float));
  3295. m = dz->buflen;
  3296. } else
  3297. m = 0;
  3298. }
  3299. }
  3300. *obufpos = m;
  3301. return(FINISHED);
  3302. }
  3303. /************************** DO_ENVGRAIN_ZEROWRITE **********************/
  3304. int do_envgrain_zerowrite(int startsearch,int endsearch,int *obufpos,dataptr dz)
  3305. {
  3306. int exit_status;
  3307. int n, m;
  3308. float *obuf = dz->sampbuf[1];
  3309. m = *obufpos;
  3310. for(n=startsearch;n <endsearch;n++) {
  3311. if(m >= dz->buflen) {
  3312. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  3313. return(exit_status);
  3314. m = 0;
  3315. }
  3316. obuf[m++] = 0.0;
  3317. }
  3318. *obufpos = m;
  3319. return(FINISHED);
  3320. }
  3321. /************************** DO_ENVGRAIN_ZEROWRITE_DBLBUF **********************/
  3322. int do_envgrain_zerowrite_dblbuf(int startsearch,int endsearch,int *obufpos,dataptr dz)
  3323. {
  3324. int exit_status;
  3325. int n, m;
  3326. float *obuf = dz->sampbuf[1], *obuf2 = dz->sampbuf[2];
  3327. m = *obufpos;
  3328. for(n=startsearch;n <endsearch;n++) {
  3329. if(m >= dz->buflen * 2) {
  3330. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  3331. return(exit_status);
  3332. memcpy((char *)obuf,(char *)obuf2,dz->buflen * sizeof(float));
  3333. memset((char *)obuf2,0,dz->buflen * sizeof(float));
  3334. m -= dz->buflen;
  3335. }
  3336. obuf[m++] = 0.0;
  3337. }
  3338. *obufpos = m;
  3339. return(FINISHED);
  3340. }
  3341. /************************** DO_ENVGRAIN_ADDWRITE **********************/
  3342. int do_envgrain_addwrite(int startsearch,int endsearch,int *last_total_samps_read,int *obufpos,dataptr dz)
  3343. {
  3344. int exit_status;
  3345. int step, n, m;
  3346. float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1], *obuf2 = dz->sampbuf[2];
  3347. if(*obufpos < 0) {
  3348. sprintf(errstr,"GRAIN TOO LARGE TO BACKTRACK IN BUFFER.\n");
  3349. return(GOAL_FAILED);
  3350. }
  3351. if(startsearch > dz->total_samps_read || startsearch < *last_total_samps_read) {
  3352. step = (startsearch / dz->buflen) * dz->buflen;
  3353. if((sndseekEx(dz->ifd[0],step,0))<0) {
  3354. sprintf(errstr,"seek error 6\n");
  3355. return(SYSTEM_ERROR);
  3356. }
  3357. *last_total_samps_read = step;
  3358. if((exit_status = read_samps(ibuf,dz))<0)
  3359. return(exit_status);
  3360. dz->total_samps_read = *last_total_samps_read + dz->ssampsread;
  3361. }
  3362. startsearch -= *last_total_samps_read;
  3363. endsearch -= *last_total_samps_read;
  3364. m = *obufpos;
  3365. for(n=startsearch;n <endsearch;n++) {
  3366. if(n >= dz->buflen) {
  3367. *last_total_samps_read = dz->total_samps_read;
  3368. if((exit_status = read_samps(ibuf,dz))<0)
  3369. return(exit_status);
  3370. n = 0;
  3371. endsearch -= dz->buflen;
  3372. }
  3373. obuf[m++] += ibuf[n];
  3374. if(m >= dz->buflen * 2) {
  3375. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  3376. return(exit_status);
  3377. memcpy((char *)obuf,(char *)obuf2,dz->buflen * sizeof(float));
  3378. memset((char *)obuf2,0,dz->buflen * sizeof(float));
  3379. m -= dz->buflen;
  3380. }
  3381. }
  3382. *obufpos = m;
  3383. return(FINISHED);
  3384. }
  3385. /****************************** TIMESTRETCH_ITERATIVE ****************************/
  3386. int timestretch_iterative3(dataptr dz)
  3387. {
  3388. int exit_status;
  3389. float *obuf = dz->sampbuf[0];
  3390. int *pos = dz->lparray[0];
  3391. int peakcnt, startsearch, endsearch, local_minima_cnt, minimum_element_len;
  3392. int n,z = 0, outpos, samps_to_write;
  3393. char *outfilename;
  3394. int namelen = strlen(dz->wordstor[0]);
  3395. if((outfilename = (char *)malloc(namelen + 4))==NULL) {
  3396. sprintf(errstr,"Insufficient memory\n");
  3397. return(MEMORY_ERROR);
  3398. }
  3399. strcpy(outfilename,dz->wordstor[0]);
  3400. fprintf(stdout,"INFO: Generating output.\n");
  3401. fflush(stdout);
  3402. if(sloom)
  3403. display_virtual_time(0,dz);
  3404. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  3405. return(exit_status);
  3406. dz->sampbuf[0][dz->insams[0]] = dz->sampbuf[0][dz->insams[0] - 1]; /* wrap around point for interpolation */
  3407. startsearch = (int)round(dz->param[RRR_START] * dz->infile->srate);
  3408. endsearch = (int)round(dz->param[RRR_END] * dz->infile->srate);
  3409. /* FIND ALL POSITIVE PEAKS : always look only at +ve vals, so all zero-crossings eventually found will be from +ve to -ve */
  3410. peakcnt = 0;
  3411. if((exit_status = find_all_positive_peaks(startsearch,endsearch,&peakcnt,dz)) < 0)
  3412. return(exit_status);
  3413. /* FIND ALL POSITIVE-PEAK MINIMA : overwriting the arrays peak-vals & peak-position with minima-vals & minima-positions */
  3414. local_minima_cnt = 0;
  3415. if((exit_status = find_all_local_minima(peakcnt,&local_minima_cnt,dz)) < 0)
  3416. return(exit_status);
  3417. /* ELIMINATE SPURIOUS MINIMA */
  3418. if((exit_status = eliminate_spurious_minima(&local_minima_cnt,&minimum_element_len,dz)) < 0)
  3419. return (exit_status);
  3420. fprintf(stdout,"INFO: Original number of iterated segments found = %d\n",local_minima_cnt - 1);
  3421. fflush(stdout);
  3422. /* CHECK MINIMA FOUND AGAINST INPUT ESTIMATE */
  3423. if((local_minima_cnt - 1) >= 2 * dz->iparam[RRR_GET]) {
  3424. if((exit_status = eliminate_excess_minima(&local_minima_cnt,pos,dz)) < 0)
  3425. return (exit_status);
  3426. fprintf(stdout,"INFO: Reduced to = %d\n",local_minima_cnt - 1);
  3427. fflush(stdout);
  3428. }
  3429. /* SEARCH FOR ZERO CROSSINGS AFTER MINIMA */
  3430. if(local_minima_cnt > 999) {
  3431. sprintf(errstr,"Found more than 999 segments. Process terminated.\n");
  3432. return(GOAL_FAILED);
  3433. }
  3434. if((exit_status = locate_zero_crossings(local_minima_cnt,dz)) < 0)
  3435. return (exit_status);
  3436. /* COPY SOUND START TO OUTBUF */
  3437. outpos = 0;
  3438. if (pos[0] > 0) {
  3439. fprintf(stdout,"INFO: Cutting start of sound\n");
  3440. fflush(stdout);
  3441. }
  3442. if((exit_status = write_samps(obuf,pos[0],dz))<0)
  3443. return(exit_status);
  3444. outpos = pos[0];
  3445. for (n = 1; n < local_minima_cnt; n++) {
  3446. if((exit_status = headwrite(dz->ofd,dz))<0) {
  3447. return(exit_status);
  3448. }
  3449. if(sndcloseEx(dz->ofd) < 0) {
  3450. fprintf(stdout,"WARNING: Can't close output soundfile %s\n",outfilename);
  3451. fflush(stdout);
  3452. }
  3453. z++;
  3454. strcpy(outfilename,dz->wordstor[0]);
  3455. if(!sloom)
  3456. insert_new_number_at_filename_end(outfilename,n,0);
  3457. else
  3458. insert_new_number_at_filename_end(outfilename,n,1);
  3459. if((exit_status = create_sized_outfile(outfilename,dz))<0) {
  3460. sprintf(errstr,"WARNING: Can't create output soundfile %s\n",outfilename);
  3461. return(SYSTEM_ERROR);
  3462. }
  3463. if(n==1) {
  3464. fprintf(stdout,"INFO: Cutting each iterated segment\n");
  3465. fflush(stdout);
  3466. }
  3467. obuf = dz->sampbuf[0] + outpos;
  3468. samps_to_write = pos[n] - pos[n-1];
  3469. if((exit_status = write_samps(obuf,samps_to_write,dz))<0)
  3470. return(exit_status);
  3471. outpos = pos[n];
  3472. }
  3473. if((exit_status = headwrite(dz->ofd,dz))<0) {
  3474. free(outfilename);
  3475. return(exit_status);
  3476. }
  3477. if(sndcloseEx(dz->ofd) < 0) {
  3478. fprintf(stdout,"WARNING: Can't close output soundfile %s\n",outfilename);
  3479. fflush(stdout);
  3480. }
  3481. z++;
  3482. if(pos[n-1] < dz->insams[0]) {
  3483. fprintf(stdout,"INFO: Cutting end of sound\n");
  3484. fflush(stdout);
  3485. strcpy(outfilename,dz->wordstor[0]);
  3486. if(!sloom)
  3487. insert_new_number_at_filename_end(outfilename,n,0);
  3488. else
  3489. insert_new_number_at_filename_end(outfilename,n,1);
  3490. if((exit_status = create_sized_outfile(outfilename,dz))<0) {
  3491. sprintf(errstr,"WARNING: Can't create output soundfile %s\n",outfilename);
  3492. return(SYSTEM_ERROR);
  3493. }
  3494. obuf = dz->sampbuf[0] + outpos;
  3495. samps_to_write = dz->insams[0] - pos[n-1];
  3496. if((exit_status = write_samps(obuf,samps_to_write,dz))<0)
  3497. return(exit_status);
  3498. z++;
  3499. }
  3500. fprintf(stdout,"INFO: Total no of outfiles = %d\n",z);
  3501. fflush(stdout);
  3502. return(FINISHED);
  3503. }