| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744 |
- /*
- * Copyright (c) 1983-2023 Trevor Wishart and Composers Desktop Project Ltd
- * http://www.trevorwishart.co.uk
- * http://www.composersdesktop.com
- *
- This file is part of the CDP System.
-
- The CDP System is free software; you can redistribute it
- and/or modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The CDP System is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License aint with the CDP System; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA
- *
- */
- /* floatsam vesion */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <memory.h>
- #include <structures.h>
- #include <tkglobals.h>
- #include <globcon.h>
- #include <processno.h>
- #include <modeno.h>
- #include <arrays.h>
- #include <grain.h>
- #include <cdpmain.h>
- #define maxtime scalefact
- #include <sfsys.h>
- #include <osbind.h>
- #include <grain.h>
- #ifndef HUGE
- #define HUGE 3.40282347e+38F
- #endif
- //#ifdef unix
- #define round(x) lround((x))
- //#endif
- static int copygrain_from_elsewhere(int len,int k,int *obufposition,dataptr dz);
- static int store_the_grain_time(int grainstart,int *graincnt,int crosbuf,double samptotime,int init,dataptr dz);
- static int retime_grain(int ibufpos,int thisgap,int grainstart,int origgap,int bufno,int *obufpos,
- int chans,int crosbuf,int *grainadjusted,int store_end,int is_first_grain,dataptr dz);
- static int keep_non_omitted_grains(int ibufpos,int bufno,int grainstart,int *graincnt,
- int *obufpos,int crosbuf,int chans,int is_first_grain,dataptr dz);
- static int do_the_reordered_grains(int ibufpos,int bufno,int grainstart,int *graincnt,
- int *obufpos,int crosbuf,int chans,int is_first_grain,int is_last_grain,dataptr dz);
- static int synchronise_the_grain(int ibufpos,int *graincnt,int bufno,int gapcnt,int *obufpos,
- int grainstart,int crosbuf,int chans,int *grainadjusted,int is_first_grain,dataptr dz);
- static int do_final_reorder_grains(int graincnt,int *obufpos,dataptr dz);
- //TW REVISED
- static int output_final_grain(int grainstart,int start_splice,int bufno,int splicestart_bufno,int is_first_grain,
- int *obufpos,int grainlen,int crosbuf,dataptr dz);
- static int do_rerhythm_grain(int ibufpos,int *graincnt,int bufno,int gapcnt,int *obufpos,int grainstart,
- int crosbuf,int chans,int *grainadjusted,int is_first_grain,dataptr dz);
- static void swap_array_adresses_and_lens_for_reordr(int n,int m,dataptr dz);
- static int copy_grain_to_buf(int ibufpos,int bufno,int grainstart,int crosbuf,int chans,int n,dataptr dz);
- //TW REVISED
- static int retime_pre_firstgrain_material
- (int new_grainstart,int *obufposition,int chans,int crosbuf,dataptr dz);
- static int output_grain_link(int thisgap,int abs_halfsplice,int *obufposition,dataptr dz);
- static int copy_start_of_grain(int grainstart,int start_splice,int bufno,int splicestart_bufno,
- int *obufpos,int crosbuf,dataptr dz);
- static int read_dn_halfsplice(int *obufposition,int len,dataptr dz);
- static int create_an_upsplice_from_pregrain_material(int obufpos,int chans,dataptr dz);
- static int duplicate_grain(int ibufpos,int bufno,int gapcnt,int *obufpos,int grainstart,
- int crosbuf,int chans,int *grainadjusted,int is_first_grain,dataptr dz);
- static int prepare_final_grain(int ibufpos,int *start_splice,int bufno,int *splicestart_bufno,
- int grainstart,int *grainlen,int crosbuf,int chans,dataptr dz);
- static int read_up_halfsplice(int *obufposition,int len,dataptr dz);
- static int store_up_halfsplice(int storeno,int start,int bufno,int chans,int splicelen,dataptr dz);
- static int store_dn_halfsplice(int start,int bufno,int chans,int splicelen,dataptr dz);
- //TW REVISED
- static int duplicate_last_grain(int ibufpos,int bufno,int *obufpos,int grainstart,
- int crosbuf,int chans,int is_first_grain,dataptr dz);
- static int store_upsplice_of_next_grain(int ibufpos,int bufno,int abs_halfsplice,int chans,dataptr dz);
- static int copy_last_grain_to_buf(int ibufpos,int bufno,int grainstart,int crosbuf,int chans,int n,dataptr dz);
- static int copy_up_halfsplice_to_grainstore(int len,int storeno,int storelen,int *storepos,dataptr dz);
- static int copy_dn_halfsplice_to_grainstore(int len,int storeno,int storelen,int storepos,dataptr dz);
- static int copy_midgrain_to_store(int mid_grainlen,int bufno,int storelen,int grainstart,
- int *storepos,int crosbuf,int storeno,dataptr dz);;
- static int put_grain_into_store(int is_last_grain,int ibufpos,int bufno,int grainstart,
- int crosbuf,int chans,int graincnt,dataptr dz);
- static int save_abs_sampletime_of_grain(int grainstart,int *graincnt,int crosbuf,dataptr dz);
- static int do_seek_and_read(int *seekbufs, int *seeksamps,int grainno,dataptr dz);
- static int test_buffer_overflows(float *obuf,int *obufpos,int *ibufpos,int n,int maxlen,int *crosbuf,dataptr dz);
- static int do_the_reversing_process(int graincnt,int *obufposition,int chans,dataptr dz);
- static int output_up_halfsplice(int *ibufpos,int *obufpos,int chans,int splicelen,int *crosbuf,dataptr dz);
- static int output_dn_halfsplice(int *ibufpos,int *obufpos,int chans,int splicelen,int *crosbuf,dataptr dz);
- static int copy_midgrain_to_output(int mid_grainlen,int *ibufpos,int *obufpos,int *crosbuf,int chans,dataptr dz);
- static int insert_EOF_sampletime_in_samptime_list(int graincnt,dataptr dz);
- static void adjust_for_last_grain(int *graincnt,int *grainpos,dataptr dz);
- static int clear_outbuf(dataptr dz);
- static int output_whole_grain(int n,int *obufpos,int *seeksamps,int *seekbufs,
- int halfsplice,int abs_splicelen,int chans,dataptr dz);
- static int adjust_firstgrain_upsplice(int *ibufpos,int *startsplice,int n,int chans);
- static int do_grain_repitching(int *actual_grainlen,int bufno,int grainstart,
- int new_grainlen,int orig_grainlen,int chans,int crosbuf,double pichratio,dataptr dz);
- static int test_for_bufcros(int *thishere,float **b,int bufno,int crosbuf,dataptr dz);
- static int save_nextgrain_upsplice_elsewhere(int ibufpos,int bufno,int abs_halfsplice,int halfsplice,
- int chans,dataptr dz);
- static int copygrain_from_grainbuf_to_outbuf(int *obufpos,int grainlen,dataptr dz);
- static int retrieve_upsplice_for_nextgrain(int abs_halfsplice,dataptr dz);
- static int save_origgrain_length_and_store_nextgrains_upsplice(int *orig_grainlen,int ibufpos,int bufno,
- int grainstart,int abs_halfsplice,int halfsplice,int crosbuf,int chans,int is_last_grain,dataptr dz);
- //TW REVISED
- static int create_repitched_and_retimed_grain(int bufno,int grainstart,int orig_grainlen,
- int *new_grainlen,double pichratio,double timeratio,int *obufpos,int *is_first_grain,
- int *grainadjusted,int abs_halfsplice,int chans,int crosbuf,dataptr dz);
- static int repitch_main_body_of_grain(int bufno,int grainstart,int new_grainlen,int orig_grainlen,
- double pichratio,int chans,int crosbuf,int halfsplice,int abs_halfsplice,dataptr dz);
- //TW REVISED
- static int retime_main_body_of_grain(int grainstart,int bufno,double pichratio,
- double timeratio,int chans,int crosbuf,int *grainadjusted,
- int orig_grainlen,int *new_grainlen,dataptr dz);
- static int repitching_process(int ibufpos,int bufno,int grainstart,int abs_halfsplice,int halfsplice,
- int *graincnt,int *obufpos,int *orig_grainlen,int *new_grainlen,int *grainadjusted,
- int *is_first_grain,int is_last_grain,int chans,int crosbuf,dataptr dz);
- static int repitching_and_retiming_process(int ibufpos,int bufno,int grainstart,int abs_halfsplice,
- int halfsplice,int *graincnt,int *obufpos,int *orig_grainlen,int *new_grainlen,
- int *grainadjusted,int *is_first_grain,int is_last_grain,int chans,int crosbuf,dataptr dz);
- static int do_in_situ_halfsplice_on_stored_grain(int bufpos,int chans,int splicelen,int grainstorelen,dataptr dz);
- static int locate_zero_crossings(int local_minima_cnt,dataptr dz);
- static int which_minimum_to_eliminate(int minsegstartpos,int *pos,int maxseg,int segcnt,int *eliminate_pos,dataptr dz);
- static int eliminate_excess_minima(int *local_minima_cnt,int *pos,dataptr dz);
- static int find_all_local_minima(int peakcnt,int *local_minima_cnt,dataptr dz);
- static int find_all_positive_peaks(int startsearch,int endsearch,int *peakcnt,dataptr dz);
- static int eliminate_spurious_minima(int *local_minima_cnt,int *minimum_element_len,dataptr dz);
- static void hhshuflup(int k,int setlen,int *perm);
- static void hhprefix(int m,int setlen,int *perm);
- static void hhinsert(int m,int t,int setlen,int *perm);
- static void do_repet_restricted_perm(int *arr, int *perm, int arrsiz, int allowed, int endval);
- static int rand_ints_with_restricted_repeats(int element_cnt,int max_elements_needed,int arrsiz,int fullperms,int **pattern,dataptr dz);
- static int extract_rrr_env_from_sndfile(int paramno,dataptr dz);
- static void get_rrrenv_of_buffer(int samps_to_process,int envwindow_sampsize,float **envptr,float *buffer);
- static float getmaxsampr(int startsamp, int sampcnt,float *buffer);
- static int do_envgrain_write(int startsearch,int endsearch,int *last_total_samps_read,int *obufpos,dataptr dz);
- static int do_envgrain_zerowrite(int startsearch,int endsearch,int *obufpos,dataptr dz);
- static int do_envgrain_addwrite(int startsearch,int endsearch,int *last_total_samps_read,int *obufpos,dataptr dz);
- static int do_envgrain_zerowrite_dblbuf(int startsearch,int endsearch,int *obufpos,dataptr dz);
- /************************** DO_THE_GRAIN **********************/
- int do_the_grain(int ibufpos,int *graincnt,int bufno,int gapcnt,int *obufpos,int grainstart,
- int crosbuf,int chans,int *grainadjusted,double samptotime,
- int *is_first_grain,dataptr dz)
- {
- int exit_status;
- int is_last_grain = FALSE;
- int newgapcnt, orig_grainlen, new_grainlen;
- int abs_splicelen = dz->iparam[GR_ABS_SPLICELEN];
- int abs_halfsplice = abs_splicelen/2; /* guaranteed to fall on stereo boundary */
- int halfsplice = dz->iparam[GR_SPLICELEN]/2;
- int store_end;
- static int init = 1;
- switch(dz->process) {
- case(GRAIN_COUNT):
- (*graincnt)++;
- break;
- case(GRAIN_GET):
- case(GRAIN_ALIGN):
- if((exit_status = store_the_grain_time(grainstart,graincnt,crosbuf,samptotime,init,dz))<0)
- return(exit_status);
- init = 0;
- break;
- case(GRAIN_REPITCH):
- if((exit_status = repitching_process(ibufpos,bufno,grainstart,abs_halfsplice,halfsplice,graincnt,
- obufpos,&orig_grainlen,&new_grainlen,grainadjusted,is_first_grain,is_last_grain,chans,crosbuf,dz))<0)
- return(exit_status);
- if((exit_status = retrieve_upsplice_for_nextgrain(abs_halfsplice,dz))<0)
- return(exit_status);
- break;
- case(GRAIN_REMOTIF):
- if((exit_status = repitching_and_retiming_process(ibufpos,bufno,grainstart,abs_halfsplice,halfsplice,graincnt,
- obufpos,&orig_grainlen,&new_grainlen,grainadjusted,is_first_grain,is_last_grain,chans,crosbuf,dz))<0)
- return(exit_status);
- if((exit_status = retrieve_upsplice_for_nextgrain(abs_halfsplice,dz))<0)
- return(exit_status);
- break;
- case(GRAIN_RERHYTHM):
- if((exit_status = do_rerhythm_grain
- (ibufpos,graincnt,bufno,gapcnt,obufpos,grainstart,crosbuf,chans,grainadjusted,*is_first_grain,dz))<0)
- return(exit_status);
- break;
- case(GRAIN_OMIT):
- if((exit_status = keep_non_omitted_grains
- (ibufpos,bufno,grainstart,graincnt,obufpos,crosbuf,chans,*is_first_grain,dz))<0)
- return(exit_status);
- break;
- case(GRAIN_REORDER):
- if((exit_status = do_the_reordered_grains
- (ibufpos,bufno,grainstart,graincnt,obufpos,crosbuf,chans,*is_first_grain,is_last_grain,dz))<0)
- return(exit_status);
- break;
- case(GRAIN_DUPLICATE):
- if((exit_status = duplicate_grain
- (ibufpos,bufno,gapcnt,obufpos,grainstart,crosbuf,chans,grainadjusted,*is_first_grain,dz))<0)
- return(exit_status);
- break;
- case(GRAIN_TIMEWARP):
- newgapcnt = round((double)(gapcnt/chans) * dz->param[GR_TSTRETCH]) * chans;
- store_end = TRUE;
- if((exit_status = retime_grain
- (ibufpos,newgapcnt,grainstart,gapcnt,bufno,obufpos,chans,crosbuf,grainadjusted,store_end,*is_first_grain,dz))<0)
- return(exit_status);
- break;
- case(GRAIN_REVERSE):
- if(*is_first_grain) {
- fprintf(stdout,"INFO: Searching for grains\n");
- fflush(stdout);
- }
- if((exit_status = save_abs_sampletime_of_grain(grainstart,graincnt,crosbuf,dz))<0)
- return(exit_status);
- break;
- case(GRAIN_POSITION):
- if((exit_status = synchronise_the_grain
- (ibufpos,graincnt,bufno,gapcnt,obufpos,grainstart,crosbuf,chans,grainadjusted,*is_first_grain,dz))<0)
- return(exit_status);
- if(exit_status!=CONTINUE)
- return(FINISHED);
- break;
- default:
- sprintf(errstr,"Unknown case in do_the_grain()\n");
- return(PROGRAM_ERROR);
- }
- *is_first_grain = FALSE;
- return(CONTINUE);
- }
- /************************** STORE_THE_GRAIN_TIME **********************/
- int store_the_grain_time(int grainstart,int *graincnt,int crosbuf,double samptotime,int init,dataptr dz)
- {
- int previous_total_ssampsread = dz->total_samps_read - dz->ssampsread;
- int sampcnt = grainstart + previous_total_ssampsread;
- if(init) {
- if(*graincnt == 0) {
- sprintf(errstr,"No grains found.\n");
- return(GOAL_FAILED);
- }
- if((dz->parray[GR_SYNCTIME] = (double *)malloc(*graincnt * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to store sync times.\n");
- return(MEMORY_ERROR);
- }
- dz->iparam[GR_SYNCCNT] = *graincnt;
- *graincnt = 0;
- } else if(dz->parray[GR_SYNCTIME] == NULL) {
- sprintf(errstr,"No grains found.\n");
- return(GOAL_FAILED);
- }
- if(crosbuf)
- sampcnt -= dz->buflen;
- dz->parray[GR_SYNCTIME][(*graincnt)++] = (double)sampcnt * samptotime;
- if(*graincnt > dz->iparam[GR_SYNCCNT]) {
- sprintf(errstr,"Error in memory asignment for storing grain times.\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- /************************* KEEP_NON_OMITTED_GRAINS *************************/
- int keep_non_omitted_grains
- (int ibufpos,int bufno,int grainstart,int *graincnt,int *obufpos,int crosbuf,int chans,int is_first_grain,dataptr dz)
- {
- int exit_status;
- int start_splice;
- int abs_splicelen = dz->iparam[GR_ABS_SPLICELEN];
- int abs_halfsplice = abs_splicelen/2; /* guaranteed to fall on stereo boundary */
- int halfsplice = dz->iparam[GR_SPLICELEN]/2;
- int splicestart_bufno = bufno;
- /* Write previously stored up_splice to THIS grain */
- if(*graincnt<dz->iparam[GR_KEEP] &&!is_first_grain) {
- if((exit_status = read_up_halfsplice(obufpos,abs_halfsplice,dz))<0)
- return(exit_status);
- }
- start_splice = ibufpos - abs_halfsplice; /* ALWAYS KEEP up_splice to NEXT grain */
- if(start_splice < 0) {
- splicestart_bufno = !bufno;
- start_splice += dz->buflen;
- }
- if((exit_status = store_up_halfsplice(1,start_splice,splicestart_bufno,chans,halfsplice,dz))<0)
- return(exit_status);
- if(*graincnt<dz->iparam[GR_KEEP]) {
- start_splice -= abs_halfsplice;
- if(start_splice < 0) {
- splicestart_bufno = !bufno;
- start_splice += dz->buflen;
- }
- if((exit_status = store_dn_halfsplice(start_splice,splicestart_bufno,chans,halfsplice,dz))<0)
- return(exit_status);
- if((exit_status = copy_start_of_grain(grainstart,start_splice,bufno,splicestart_bufno,obufpos,crosbuf,dz))<0)
- return(exit_status);
- if((exit_status = read_dn_halfsplice(obufpos,abs_halfsplice,dz))<0)
- return(exit_status);
- }
- if(++(*graincnt)>=dz->iparam[GR_OUT_OF])
- *graincnt = 0;
- return(FINISHED);
- }
- /************************* DO_THE_REORDERED_GRAINS *************************/
- int do_the_reordered_grains(int ibufpos,int bufno,int grainstart,int *graincnt,
- int *obufpos,int crosbuf,int chans,int is_first_grain,int is_last_grain,dataptr dz)
- {
- int exit_status;
- int n, m, k;
- int len;
- int abs_halfsplice = dz->iparam[GR_ABS_SPLICELEN]/2; /* guaranteed to fall on stereo boundary */
- if(*graincnt > dz->iparam[GR_REOLEN]) { /* WE'RE BEYOND PERMUTE-SET: LOOKING AT GRAINS NOT USED */
- if(*graincnt == dz->iparam[GR_REOSTEP]-1) { /* IF looking at very last unused grain */
- if((exit_status = store_upsplice_of_next_grain(ibufpos,bufno,abs_halfsplice,chans,dz))<0)
- return(exit_status);/* store startsplice of nextgrain, found at end of final skipped grain */
- *graincnt = -1; /* and reset grain counter to indicate end of skipped-over grains */
- } /* Otherwise, completely ignore skipped over grain */
- } else if(*graincnt == dz->iparam[GR_REOLEN]) { /* WE'VE REACHED THE END OF THE PERMUTABLE SET */
- for(n=0;n<dz->iparam[GR_REOCNT];n++) {
- k = dz->iparray[GR_REOSET][n]; /* write permuted set to outbuf */
- len = dz->lparray[GR_THIS_LEN][k];
- if((exit_status = copygrain_from_elsewhere(len,k,obufpos,dz))<0)
- return(exit_status);
- }
- if(dz->iparam[GR_REOSTEP] < dz->iparam[GR_REOLEN]) { /* IF NEXT PERMUTE SET BEGINS BEFORE END OF THIS */
- for(n=0,m=dz->iparam[GR_REOSTEP];m < dz->iparam[GR_REOLEN];n++,m++)
- swap_array_adresses_and_lens_for_reordr(n,m,dz); /* recycle the buffer storage */
- *graincnt = dz->iparam[GR_REOLEN] - dz->iparam[GR_REOSTEP]; /* & reduce graincnt to no. of reused grains */
- if((exit_status = put_grain_into_store(is_last_grain,ibufpos,bufno,grainstart,crosbuf,chans,*graincnt,dz))<0)
- return(exit_status); /* Store the current grain */
- } else if(dz->iparam[GR_REOSTEP] == dz->iparam[GR_REOLEN]) { /* IF IT BEGINS AT END OF THIS ONE */
- *graincnt = 0; /* reset grain counter to zero, for next set */
- if((exit_status = put_grain_into_store(is_last_grain,ibufpos,bufno,grainstart,crosbuf,chans,*graincnt,dz))<0)
- return(exit_status); /* Store the current grain */
- } else if (dz->iparam[GR_REOSTEP] == dz->iparam[GR_REOLEN]+1) {/* IF IT BEGINS AT 1st GRAIN BEYOND THIS SET */
- if((exit_status = store_upsplice_of_next_grain(ibufpos,bufno,abs_halfsplice,chans,dz))<0)
- return(exit_status);/* store startsplice of nextgrain, found at end of final skipped grain */
- *graincnt = -1; /* and reset grain counter to indicate end of skipped-over grains */
- } /* IF IT BEGINS BEYOND THAT : DO NOTHING */
- } else { /* WE'RE AT START OF, OR WITHIN, PERMUTABLE SET */
- if(is_first_grain) {
- if((exit_status = create_an_upsplice_from_pregrain_material(*obufpos,chans,dz))<0)
- return(exit_status); /* Generate upsplice to 1st grain, of correct size */
- memset((char *)dz->sampbuf[2],0,(size_t)dz->buflen * sizeof(float));
- *obufpos = 0;
- }
- if((exit_status = put_grain_into_store(is_last_grain,ibufpos,bufno,grainstart,crosbuf,chans,*graincnt,dz))<0)
- return(exit_status); /* Store the current grain */
- }
- (*graincnt)++;
- return(FINISHED);
- }
- /*********************** SYNCHRONISE_THE_GRAIN ***************************/
- int synchronise_the_grain(int ibufpos,int *graincnt,int bufno,int gapcnt,int *obufpos,
- int grainstart,int crosbuf,int chans,int *grainadjusted,int is_first_grain,dataptr dz)
- {
- int exit_status;
- int newgapcnt;
- int store_end = TRUE;
- if(*graincnt >= dz->iparam[GR_SYNCCNT])
- return(FINISHED);
- newgapcnt = round(dz->parray[GR_SYNCTIME][*graincnt]);
- if(*graincnt==0) {
- if((exit_status = retime_pre_firstgrain_material(newgapcnt,obufpos,chans,crosbuf,dz))<0)
- return(exit_status);
- (*graincnt)++;
- }
- newgapcnt = round(dz->parray[GR_SYNCTIME][*graincnt]);
- if((exit_status = retime_grain(ibufpos,newgapcnt,grainstart,gapcnt,
- bufno,obufpos,chans,crosbuf,grainadjusted,store_end,is_first_grain,dz))<0)
- return(exit_status);
- (*graincnt)++;
- return(CONTINUE);
- }
- /************************* DEAL_WITH_LAST_GRAINS *************************/
- //TW REVISED
- int deal_with_last_grains
- (int ibufpos,int bufno,int *graincnt,int grainstart,int *grainadjusted,
- int *obufpos,int crosbuf,int chans,double samptotime,int *is_first_grain,dataptr dz)
- {
- int exit_status;
- int is_last_grain = TRUE;
- int abs_splicelen = dz->iparam[GR_ABS_SPLICELEN];
- int abs_halfsplice = abs_splicelen/2; /* guaranteed to fall on stereo boundary */
- int halfsplice = dz->iparam[GR_SPLICELEN]/2;
- int n, start_splice, grainlen, orig_grainlen, new_grainlen;
- int splicestart_bufno;
- switch(dz->process) {
- case(GRAIN_COUNT):
- if(!dz->vflag[LOSE_LAST_GRAIN])
- (*graincnt)++;
- sprintf(errstr,"%d grains found at this gate level.\n",*graincnt);
- break;
- case(GRAIN_GET):
- if(!dz->vflag[LOSE_LAST_GRAIN]) {
- if((exit_status = store_the_grain_time(grainstart,graincnt,crosbuf,samptotime,0,dz))<0)
- return(exit_status);
- }
- for(n=0;n < *graincnt;n++)
- fprintf(dz->fp,"%lf\n",dz->parray[GR_SYNCTIME][n]);
- break;
- case(GRAIN_REVERSE):
- if((exit_status = save_abs_sampletime_of_grain(grainstart,graincnt,crosbuf,dz))<0)
- return(exit_status);
- if(*graincnt <= 1) {
- sprintf(errstr,"No grains found.\n");
- return(DATA_ERROR);
- }
- fprintf(stdout,"INFO: Reversing grain order\n");
- fflush(stdout);
- if((exit_status = do_the_reversing_process(*graincnt,obufpos,chans,dz))<0)
- return(exit_status);
- break;
- case(GRAIN_ALIGN):
- if(!dz->vflag[LOSE_LAST_GRAIN]) {
- if((exit_status = store_the_grain_time(grainstart,graincnt,crosbuf,samptotime,0,dz))<0)
- return(exit_status);
- }
- if(dz->iparam[GR_SYNCCNT] != *graincnt)
- dz->iparam[GR_SYNCCNT] = *graincnt;
- break;
- case(GRAIN_REORDER):
- if(!dz->vflag[LOSE_LAST_GRAIN]) {
- if((exit_status = do_the_reordered_grains
- (ibufpos,bufno,grainstart,graincnt,obufpos,crosbuf,chans,*is_first_grain,is_last_grain,dz))<0)
- return(exit_status);
- }
- if((exit_status = do_final_reorder_grains(*graincnt,obufpos,dz))<0)
- return(exit_status);
- break;
- case(GRAIN_RERHYTHM):
- case(GRAIN_TIMEWARP):
- case(GRAIN_POSITION):
- if(!dz->vflag[LOSE_LAST_GRAIN]) {
- if((exit_status = prepare_final_grain
- (ibufpos,&start_splice,bufno,&splicestart_bufno,grainstart,&grainlen,crosbuf,chans,dz))<0)
- return(exit_status);
- if(exit_status==FINISHED)
- break;
- if((exit_status = output_final_grain
- //TW REVISED
- (grainstart,start_splice,bufno,splicestart_bufno,*is_first_grain,obufpos,grainlen,crosbuf,dz))<0)
- return(exit_status);
- }
- break;
- case(GRAIN_OMIT):
- if(!dz->vflag[LOSE_LAST_GRAIN]
- && *graincnt<dz->iparam[GR_KEEP]) {
- if((exit_status = prepare_final_grain
- (ibufpos,&start_splice,bufno,&splicestart_bufno,grainstart,&grainlen,crosbuf,chans,dz))<0)
- return(exit_status);
- if(exit_status==FINISHED)
- break;
- if((exit_status = output_final_grain
- //TW REVISED
- (grainstart,start_splice,bufno,splicestart_bufno,*is_first_grain,obufpos,grainlen,crosbuf,dz))<0)
- return(exit_status);
- }
- break;
- case(GRAIN_DUPLICATE):
- if(!dz->vflag[LOSE_LAST_GRAIN]) {
- if((exit_status = duplicate_last_grain
- //TW REVISED
- (ibufpos,bufno,obufpos,grainstart,crosbuf,chans,*is_first_grain,dz))<0)
- return(exit_status);
- }
- break;
- case(GRAIN_REPITCH):
- if(!dz->vflag[LOSE_LAST_GRAIN]) {
- if((exit_status = repitching_process(ibufpos,bufno,grainstart,abs_halfsplice,halfsplice,graincnt,
- obufpos,&orig_grainlen,&new_grainlen,grainadjusted,is_first_grain,is_last_grain,chans,crosbuf,dz))<0)
- return(exit_status);
- }
- break;
- case(GRAIN_REMOTIF):
- if(!dz->vflag[LOSE_LAST_GRAIN]) {
- if((exit_status = repitching_and_retiming_process(ibufpos,bufno,grainstart,abs_halfsplice,halfsplice,graincnt,
- obufpos,&orig_grainlen,&new_grainlen,grainadjusted,is_first_grain,is_last_grain,chans,crosbuf,dz))<0)
- return(exit_status);
- }
- break;
- default:
- sprintf(errstr,"Unknown case in deal_with_last_grains()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- /************************* DO_FINAL_REORDER_GRAINS *************************/
- int do_final_reorder_grains(int graincnt,int *obufpos,dataptr dz)
- {
- int exit_status;
- int n, k;
- int len;
- if(graincnt > 0 && graincnt <= dz->iparam[GR_REOCNT]) { /* There are grains still to permute */
- for(n=0;n<dz->iparam[GR_REOCNT];n++) {
- if((k = dz->iparray[GR_REOSET][n])>=graincnt) /* If required grain doesn't exist, finish */
- return(FINISHED);
- len = dz->lparray[GR_THIS_LEN][k];
- if((exit_status = copygrain_from_elsewhere(len,k,obufpos,dz))<0)
- return(exit_status);
- }
- }
- return(FINISHED);
- }
- /************************* DO_RERHYTHM_GRAIN *************************/
- int do_rerhythm_grain(int ibufpos,int *graincnt,int bufno,int gapcnt,
- int *obufpos,int grainstart,int crosbuf,int chans,int *grainadjusted,int is_first_grain,dataptr dz)
- {
- int exit_status;
- int newgapcnt, n;
- int store_end;
- double *ratio = dz->parray[GR_RATIO];
- switch(dz->mode) {
- case(GR_NO_REPEATS):
- store_end = TRUE;
- newgapcnt = round((double)(gapcnt/chans) * ratio[*graincnt]) * chans;
- if((exit_status = retime_grain
- (ibufpos,newgapcnt,grainstart,gapcnt,bufno,obufpos,chans,crosbuf,grainadjusted,store_end,is_first_grain,dz))<0)
- return(exit_status);
- if(++(*graincnt)>=dz->iparam[GR_RATIOCNT])
- *graincnt = 0;
- break;
- case(GR_REPEATS):
- store_end = FALSE;
- if(is_first_grain && dz->iparam[GR_RATIOCNT]>1) {
- if((exit_status = create_an_upsplice_from_pregrain_material(*obufpos,chans,dz))<0)
- return(exit_status);
- }
- for(n=0; n<dz->iparam[GR_RATIOCNT]-1; n++) {
- newgapcnt = round((double)(gapcnt/chans) * ratio[n]) * chans;
- if((exit_status = retime_grain
- (ibufpos,newgapcnt,grainstart,gapcnt,bufno,obufpos,chans,crosbuf,grainadjusted,store_end,is_first_grain,dz))<0)
- return(exit_status);
- is_first_grain = FALSE;
- }
- store_end = TRUE;
- newgapcnt = round((double)(gapcnt/chans) * ratio[n]) * chans;
- if((exit_status = retime_grain
- (ibufpos,newgapcnt,grainstart,gapcnt,bufno,obufpos,chans,crosbuf,grainadjusted,store_end,is_first_grain,dz))<0)
- return(exit_status);
- break;
- default:
- sprintf(errstr,"Unknown case in do_rerhythm_grain()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- /************************* DUPLICATE_GRAIN *************************/
- int duplicate_grain(int ibufpos,int bufno,int gapcnt,int *obufpos,int grainstart,
- int crosbuf,int chans,int *grainadjusted,int is_first_grain,dataptr dz)
- {
- int exit_status;
- int newgapcnt = gapcnt, n;
- int store_end = FALSE;
- int dupl = (int)dz->iparam[GR_DUPLS];
- if(is_first_grain && dupl>1) {
- if((exit_status = create_an_upsplice_from_pregrain_material(*obufpos,chans,dz))<0)
- return(exit_status);
- }
- for(n=0; n<dupl-1; n++) {
- if((exit_status = retime_grain
- (ibufpos,newgapcnt,grainstart,gapcnt,bufno,obufpos,chans,crosbuf,grainadjusted,store_end,is_first_grain,dz))<0)
- return(exit_status);
- is_first_grain = FALSE;
- }
- store_end = TRUE;
- if((exit_status = retime_grain
- (ibufpos,newgapcnt,grainstart,gapcnt,bufno,obufpos,chans,crosbuf,grainadjusted,store_end,is_first_grain,dz))<0)
- return(exit_status);
- return(FINISHED);
- }
- /************************* DUPLICATE_LAST_GRAIN *************************/
- //TW REVISED
- int duplicate_last_grain(int ibufpos,int bufno,int *obufpos,int grainstart,
- int crosbuf,int chans,int is_first_grain,dataptr dz)
- {
- int exit_status;
- int /*newgapcnt = gapcnt,*/ n;
- /*int store_end = FALSE;*/
- int start_splice, grainlen;
- int splicestart_bufno;
- int dupl = (int)dz->iparam[GR_DUPLS];
- if(is_first_grain && dupl>1) {
- if((exit_status = create_an_upsplice_from_pregrain_material(*obufpos,chans,dz))<0)
- return(exit_status);
- }
- if((exit_status = prepare_final_grain
- (ibufpos,&start_splice,bufno,&splicestart_bufno,grainstart,&grainlen,crosbuf,chans,dz))<0)
- return(exit_status);
- if(exit_status==FINISHED)
- return(FINISHED);
- for(n=0; n<dupl; n++) {
- //TW REVISED
- if((exit_status = output_final_grain
- (grainstart,start_splice,bufno,splicestart_bufno,is_first_grain,obufpos,grainlen,crosbuf,dz))<0)
- return(exit_status);
- is_first_grain = FALSE;
- }
- return(FINISHED);
- }
- /************************** COPYGRAIN_FROM_ELSEWHERE ******************************/
- int copygrain_from_elsewhere(int len,int k,int *obufposition,dataptr dz)
- {
- int exit_status;
- register int n, obufpos = *obufposition;
- float *obuf = dz->sampbuf[2];
- float *buf = dz->extrabuf[k+SPLBUF_OFFSET];
- for(n=0;n<len;n++) {
- obuf[obufpos++] = buf[n];
- if(obufpos >= dz->buflen) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- obufpos = 0;
- }
- }
- *obufposition = obufpos;
- return(FINISHED);
- }
- /************************* SWAP_ARRAY_ADRESSES_AND_LENS_FOR_REORDR *************************
- *
- * The arrays still needed are now pointed to by the lower-indexed lparrays.
- * The arrays NO intER required get swapped, to be pointed to by the higher-indexed lparrays,
- * hence are overwritten as the process proceeds.
- *
- * This works (I hope) even where an index is swapped over more than once!!
- */
- void swap_array_adresses_and_lens_for_reordr(int n,int m,dataptr dz)
- {
- int n_bufno = n + SPLBUF_OFFSET;
- int m_bufno = m + SPLBUF_OFFSET;
- float *tempadr = dz->extrabuf[n_bufno];
- int temp_arraylen = dz->lparray[GR_ARRAYLEN][n];
- int templen = dz->lparray[GR_THIS_LEN][n];
- dz->extrabuf[n_bufno] = dz->extrabuf[m_bufno];
- dz->extrabuf[m_bufno] = tempadr;
- dz->lparray[GR_ARRAYLEN][n] = dz->lparray[GR_ARRAYLEN][m];
- dz->lparray[GR_ARRAYLEN][m] = temp_arraylen;
- dz->lparray[GR_THIS_LEN][n] = dz->lparray[GR_THIS_LEN][m];
- dz->lparray[GR_THIS_LEN][m] = templen;
- }
- /************************* COPY_GRAIN_TO_BUF *************************/
- int copy_grain_to_buf(int ibufpos,int bufno,int grainstart,int crosbuf,int chans,int storeno,dataptr dz)
- {
- int exit_status;
- int grainlen = ibufpos - grainstart;
- int storepos = 0, mid_grainlen;
- int abs_splicelen = dz->iparam[GR_ABS_SPLICELEN];
- int abs_halfsplice = abs_splicelen/2;
- int halfsplice = dz->iparam[GR_SPLICELEN]/2;
- int splicestart;
- int grainbufno = storeno + SPLBUF_OFFSET;
- int splicestart_bufno = bufno;
- if(crosbuf)
- grainlen += dz->buflen;
- if(grainlen > dz->lparray[GR_ARRAYLEN][storeno]) {
- if((dz->extrabuf[grainbufno] = (float *)realloc(dz->extrabuf[grainbufno],grainlen * sizeof(float)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to enlarge grain store.\n");
- return(MEMORY_ERROR);
- }
- dz->lparray[GR_ARRAYLEN][storeno] = grainlen;
- }
- dz->lparray[GR_THIS_LEN][storeno] = grainlen;
- if((exit_status = copy_up_halfsplice_to_grainstore(abs_halfsplice,grainbufno,grainlen,&storepos,dz))<0)
- return(exit_status);
- splicestart = ibufpos - abs_halfsplice;
- if(splicestart < 0) {
- splicestart += dz->buflen;
- splicestart_bufno = !bufno;
- }
- if((exit_status = store_up_halfsplice(1,splicestart,splicestart_bufno,chans,halfsplice,dz))<0)
- return(exit_status);
- splicestart -= abs_halfsplice;
- if(splicestart < 0) {
- splicestart += dz->buflen;
- splicestart_bufno = !bufno;
- }
- if((exit_status = store_dn_halfsplice(splicestart,splicestart_bufno,chans,halfsplice,dz))<0)
- return(exit_status);
- mid_grainlen = grainlen - dz->iparam[GR_ABS_SPLICELEN];
- if((exit_status = copy_midgrain_to_store(mid_grainlen,bufno,grainlen,grainstart,&storepos,crosbuf,grainbufno,dz))<0)
- return(exit_status);
- if((exit_status = copy_dn_halfsplice_to_grainstore(abs_halfsplice,grainbufno,grainlen,storepos,dz))<0)
- return(exit_status);
- return(FINISHED);
- }
- /************************* COPY_LAST_GRAIN_TO_BUF *************************/
- int copy_last_grain_to_buf(int ibufpos,int bufno,int grainstart,int crosbuf,int chans,int storeno,dataptr dz)
- {
- int exit_status;
- int storepos = 0, mid_grainlen;
- int splicelen, abs_splicelen = dz->iparam[GR_ABS_SPLICELEN];
- int abs_halfsplice = abs_splicelen/2;
- int splicestart;
- int splicestart_bufno = bufno;
- int grainbufno = storeno + SPLBUF_OFFSET;
- int storelen;
- int grainlen = ibufpos - grainstart;
- if(crosbuf)
- grainlen += dz->buflen;
- if((storelen = grainlen + abs_halfsplice)<abs_splicelen)
- storelen = abs_splicelen; /* grainstore must store up_hsplice & dn_hsplice even if grain to short */
- if(storelen > dz->lparray[GR_ARRAYLEN][storeno]) {
- if((dz->extrabuf[grainbufno] = (float *)realloc(dz->extrabuf[grainbufno],storelen * sizeof(float)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to enlarge grain store.\n");
- return(MEMORY_ERROR);
- }
- dz->lparray[GR_ARRAYLEN][storeno] = storelen;
- }
- dz->lparray[GR_THIS_LEN][storeno] = storelen;
- if((exit_status = copy_up_halfsplice_to_grainstore(abs_halfsplice,grainbufno,storelen,&storepos,dz))<0)
- return(exit_status);
- if((mid_grainlen = grainlen - abs_halfsplice) < 0)
- mid_grainlen = 0; /* HENCE mid_grainlen >= 0 */
- abs_splicelen = min(grainlen,abs_halfsplice);
- splicelen = abs_splicelen/chans;
- /* HENCE abs_splicelen <= grainlen */
- splicestart = ibufpos - abs_splicelen; /* splicestart >= grainstart, BECAUSE abs_splicelen <= grainlen */
- if(splicestart < 0) {
- splicestart += dz->buflen;
- splicestart_bufno = !bufno;
- }
- if((exit_status = store_dn_halfsplice(splicestart,splicestart_bufno,chans,splicelen,dz))<0)
- return(exit_status); /* forces an abs_halfsplice length unit, regardless of input splicelen */
- if(mid_grainlen > 0) {
- if((exit_status =
- copy_midgrain_to_store(mid_grainlen,bufno,storelen,grainstart,&storepos,crosbuf,grainbufno,dz))<0)
- return(exit_status);
- }
- if((exit_status = copy_dn_halfsplice_to_grainstore(abs_halfsplice,grainbufno,storelen,storepos,dz))<0)
- return(exit_status);
- return(FINISHED);
- }
- /************************ RETIME_PRE_FIRSTGRAIN_MATERIAL ***************************/
- int retime_pre_firstgrain_material
- (int new_grainstart,int *obufposition,int chans,int crosbuf,dataptr dz)
- {
- int exit_status;
- /*float *b = dz->sampbuf[bufno];*/ /* RWD: not used */
- float *obuf = dz->sampbuf[2];
- double *splicetab = dz->parray[GR_SPLICETAB];
- int excess, n, k;
- int m;
- int obufpos = *obufposition;
- int abs_splicelen = dz->iparam[GR_ABS_SPLICELEN]/2;
- int splicelen = abs_splicelen/chans;
- if(crosbuf) {
- sprintf(errstr,"1st grain starts beyond end of sound buffer: Can't proceed.\n");
- return(DATA_ERROR);
- }
- excess = new_grainstart - obufpos;
- if(excess > 0) {
- memmove((char *)dz->extrabuf[2],(char *)obuf,(size_t)dz->buflen * sizeof(float));
- if(excess >= dz->buflen) {
- memset((char *)obuf,0,(size_t)dz->buflen * sizeof(float));
- while(excess >= dz->buflen) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- excess -= dz->buflen;
- }
- }
- for(n=0;n<excess;n++)
- obuf[n] = 0;
- for(m=0;m < obufpos;m++) {
- obuf[n++] = dz->extrabuf[2][m];
- if(n >= dz->buflen) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- n = 0;
- }
- }
- new_grainstart = n;
- } else if(excess < 0) {
- for(n=0, m = excess; n < new_grainstart; n++, m++)
- obuf[n] = obuf[m]; /* Move data backwards */
- while(n < obufpos)
- obuf[n++] = 0; /* rezero samples beyond new_grainstart */
- k = 0;
- for(n=0;n<splicelen;n++) { /* Put splice on start of file */
- for(m=0;m<chans;m++) {
- obuf[k] = (float) /*round*/ ((double)obuf[k] * splicetab[n]);
- k++;
- }
- if(k >= dz->buflen) {
- sprintf(errstr,"Buffer accounting problem: retime_pre_firstgrain_material()\n");
- return(PROGRAM_ERROR);
- }
- }
- }
- *obufposition = new_grainstart; /* reset obuf pointer to (new) END of pre-grain material */
- return(FINISHED);
- }
- /************************* OUTPUT_GRAIN_LINK *************************/
- int output_grain_link(int thisgap,int abs_halfsplice,int *obufposition,dataptr dz)
- {
- int exit_status;
- int n, m;
- float *obuf = dz->sampbuf[2];
- int obufpos = *obufposition;
- for(n = 0, m = -(thisgap - abs_halfsplice); n < thisgap; n++,m++) {
- if(n < abs_halfsplice)
- obuf[obufpos] = dz->extrabuf[0][n];
- else
- obuf[obufpos] = 0;
- if(++obufpos >= dz->buflen) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- obufpos = 0;
- }
- }
- *obufposition = obufpos;
- return(FINISHED);
- }
- /************************* COPY_START_OF_GRAIN *************************/
- int copy_start_of_grain
- (int grainstart,int start_splice,int bufno,int splicestart_bufno,int *obufpos,int crosbuf,dataptr dz)
- {
- int exit_status;
- if(crosbuf) {
- if(splicestart_bufno != bufno) {
- if((exit_status = copygrain(grainstart,start_splice,!bufno,obufpos,dz))<0)
- return(exit_status);
- } else {
- if((exit_status = crosbuf_grain_type3(grainstart,start_splice,bufno,obufpos,dz))<0)
- return(exit_status);
- }
- } else {
- if((exit_status = copygrain(grainstart,start_splice,bufno,obufpos,dz))<0)
- return(exit_status);
- }
- return(FINISHED);
- }
- /************************** PREPARE_FINAL_GRAIN ******************************/
- int prepare_final_grain(int ibufpos,int *start_splice,int bufno,int *splicestart_bufno,
- int grainstart,int *grainlen,int crosbuf,int chans,dataptr dz)
- {
- int exit_status;
- int abs_splicelen = dz->iparam[GR_ABS_SPLICELEN];
- int abs_halfsplice = abs_splicelen/2; /* guaranteed to fall on stereo boundary */
- int halfsplice = abs_halfsplice/chans;
- *grainlen = ibufpos - grainstart;
- if(crosbuf)
- *grainlen += dz->buflen;
- if(*grainlen < abs_splicelen) {
- fprintf(stdout,"INFO: Final grain omitted: too short\n");
- fflush(stdout);
- return(FINISHED);
- }
- *start_splice = ibufpos - abs_halfsplice;
- *splicestart_bufno = bufno;
- if(*start_splice < 0) {
- *splicestart_bufno = !bufno;
- *start_splice += dz->buflen;
- }
- if((exit_status = store_dn_halfsplice(*start_splice,*splicestart_bufno,chans,halfsplice,dz))<0)
- return(exit_status);
- return(CONTINUE);
- }
- /************************** OUTPUT_FINAL_GRAIN ******************************/
- //TW REVISED
- int output_final_grain(int grainstart,int start_splice,int bufno,int splicestart_bufno,int is_first_grain,
- int *obufpos,int grainlen,int crosbuf,dataptr dz)
- {
- int exit_status;
- int abs_splicelen = dz->iparam[GR_ABS_SPLICELEN];
- int abs_halfsplice = abs_splicelen/2; /* guaranteed to fall on stereo boundary */
- if(!is_first_grain) {
- if((exit_status = read_up_halfsplice(obufpos,abs_halfsplice,dz))<0)
- return(exit_status);
- }
- if(grainlen > 0) {
- if((exit_status = copy_start_of_grain(grainstart,start_splice,bufno,splicestart_bufno,obufpos,crosbuf,dz))<0)
- return(exit_status);
- }
- if((exit_status = read_dn_halfsplice(obufpos,abs_halfsplice,dz))<0)
- return(exit_status);
- return(FINISHED);
- }
- /**************************** READ_DN_HALFSPLICE ****************************/
- int read_dn_halfsplice(int *obufposition,int len,dataptr dz)
- {
- int exit_status;
- int n, j = 0;
- float *b = dz->extrabuf[0];
- float *obuf = dz->sampbuf[2];
- int obufpos = *obufposition;
- for(n=0;n < len;n++) {
- obuf[obufpos++] = b[j++];
- if(obufpos >= dz->buflen) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- obufpos = 0;
- }
- }
- *obufposition = obufpos;
- return(FINISHED);
- }
- /**************************** READ_UP_HALFSPLICE ****************************/
- int read_up_halfsplice(int *obufposition,int len,dataptr dz)
- {
- int exit_status;
- int n, j = 0;
- float *b = dz->extrabuf[1];
- float *obuf = dz->sampbuf[2];
- int obufpos = *obufposition;
- for(n=0;n < len;n++) {
- obuf[obufpos++] = b[j++];
- if(obufpos >= dz->buflen) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- obufpos = 0;
- }
- }
- *obufposition = obufpos;
- return(FINISHED);
- }
- /**************************** COPY_UP_HALFSPLICE_TO_GRAINSTORE ****************************/
- int copy_up_halfsplice_to_grainstore(int len,int storeno,int storelen,int *storepos,dataptr dz)
- {
- char *goaladdress = (char *)dz->extrabuf[storeno];
- if(len > storelen) {
- sprintf(errstr,"Buffer anomaly: copy_up_halfsplice_to_grainstore()\n");
- return(PROGRAM_ERROR);
- }
- memmove(goaladdress,(char *)dz->extrabuf[1],len * sizeof(float));
- *storepos = len;
- return(FINISHED);
- }
- /**************************** COPY_DN_HALFSPLICE_TO_GRAINSTORE ****************************/
- int copy_dn_halfsplice_to_grainstore(int len,int storeno,int storelen,int storepos,dataptr dz)
- {
- char *goaladdress = (char *)(dz->extrabuf[storeno] + storepos);
- if(storepos + len > storelen) {
- sprintf(errstr,"Buffer anomaly: copy_dn_halfsplice_to_grainstore()\n");
- return(PROGRAM_ERROR);
- }
- memmove(goaladdress,(char *)dz->extrabuf[0],len * sizeof(float));
- return(FINISHED);
- }
- /**************************** CREATE_AN_UPSPLICE_FROM_PREGRAIN_MATERIAL ****************************/
- int create_an_upsplice_from_pregrain_material(int obufpos,int chans,dataptr dz)
- {
- int n, k;
- int m, j = 0, empty_space;
- double ratio;
- float *obuf = dz->sampbuf[2];
- float *splicebuf = dz->extrabuf[1];
- int abs_halfsplice = dz->iparam[GR_ABS_SPLICELEN]/2;
- int halfsplice = abs_halfsplice/chans;
- int splicelen;
- double *splicetab = dz->parray[GR_SPLICETAB];
- if(obufpos >= abs_halfsplice) {
- k = obufpos - abs_halfsplice;
- for(n=0;n<halfsplice;n++) {
- for(m=0;m<chans;m++)
- splicebuf[j++] = (float) /*round*/ ((double)obuf[k++] * splicetab[n]);
- if(k >= dz->buflen) {
- sprintf(errstr,"Error in buffer accounting: create_an_upsplice_from_pregrain_material()\n");
- return(PROGRAM_ERROR);
- }
- }
- } else {
- splicelen = obufpos/chans;
- empty_space = abs_halfsplice - obufpos;
- for(n=0;n<empty_space;n++)
- splicebuf[j++] = 0;
- k = 0;
- for(n=0;n<splicelen;n++) {
- ratio = (double)n/(double)splicelen;
- for(m=0;m<chans;m++)
- splicebuf[j++] = (float) /*round*/ ((double)obuf[k++] * ratio);
- if(k >= dz->buflen) {
- sprintf(errstr,"Error in buffer accounting: create_an_upsplice_from_pregrain_material()\n");
- return(PROGRAM_ERROR);
- }
- }
- }
- return(FINISHED);
- }
- /************************* RETIME_GRAIN *************************/
- int retime_grain(int ibufpos,int thisgap,int grainstart,int origgap,int bufno,
- int *obufpos,int chans,int crosbuf,int *grainadjusted,int store_end,int is_first_grain,dataptr dz)
- {
- int exit_status;
- int grainend, start_splice, gapchange;
- int abs_splicelen = dz->iparam[GR_ABS_SPLICELEN];
- int abs_halfsplice = abs_splicelen/2; /* guaranteed to fall on stereo boundary */
- int halfsplice = dz->iparam[GR_SPLICELEN]/2;
- int splicestart_bufno = bufno;
- start_splice = ibufpos - abs_halfsplice;
- if(start_splice < 0) {
- splicestart_bufno = !bufno;
- start_splice += dz->buflen;
- }
- if(!is_first_grain) {
- if((exit_status = read_up_halfsplice(obufpos,abs_halfsplice,dz))<0)
- return(exit_status);
- }
- if(store_end) {
- if((exit_status = store_up_halfsplice(1,start_splice,splicestart_bufno,chans,halfsplice,dz))<0)
- return(exit_status);
- }
- if((gapchange = thisgap - origgap)>=0) {
- start_splice -= abs_halfsplice;
- if(start_splice < 0) {
- splicestart_bufno = !bufno;
- start_splice += dz->buflen;
- }
- if((exit_status = store_dn_halfsplice(start_splice,splicestart_bufno,chans,halfsplice,dz))<0)
- return(exit_status);
- if((exit_status = copy_start_of_grain(grainstart,start_splice,bufno,splicestart_bufno,obufpos,crosbuf,dz))<0)
- return(exit_status);
- if((exit_status = output_grain_link(abs_halfsplice+gapchange,abs_halfsplice,obufpos,dz))<0)
- return(exit_status);
- } else {
- if(thisgap < dz->iparam[GR_ABS_SPLICEX2]) {
- grainend = grainstart + dz->iparam[GR_ABS_SPLICEX2];
- (*grainadjusted)++;
- } else
- grainend = grainstart + thisgap;
- start_splice = grainend - abs_splicelen; /* NB Ensures 1 grain stops before other starts */
- splicestart_bufno = bufno;
- if(crosbuf) {
- if(start_splice >= dz->buflen)
- start_splice -= dz->buflen;
- else
- splicestart_bufno = !bufno;
- }
- if((exit_status = store_dn_halfsplice(start_splice,splicestart_bufno,chans,halfsplice,dz))<0)
- return(exit_status);
- if((exit_status = copy_start_of_grain(grainstart,start_splice,bufno,splicestart_bufno,obufpos,crosbuf,dz))<0)
- return(exit_status);
- if((exit_status = output_grain_link(abs_halfsplice,abs_halfsplice,obufpos,dz))<0)
- return(exit_status);
- }
- return(FINISHED);
- }
- /**************************** STORE_UP_HALFSPLICE ***************************
- *
- * GIVE IT bufno where splice STARTS!!!
- */
- int store_up_halfsplice(int storeno,int start,int bufno,int chans,int splicelen,dataptr dz)
- {
- int n, remain;
- int m;
- float *b = dz->sampbuf[bufno];
- float *obuf = dz->extrabuf[storeno];
- int k = start, j = 0;
- double *splicetab = dz->parray[GR_SPLICETAB];
- int true_halfsplice = dz->iparam[GR_SPLICELEN]/2;
- if((remain = true_halfsplice - splicelen)<0) {
- sprintf(errstr,"Invalid splicelen in store_up_halfsplice()\n");
- return(PROGRAM_ERROR);
- } else if(remain==0) {
- for(n=0;n<splicelen;n++) {
- for(m=0;m<chans;m++)
- obuf[j++] = (float) /*round*/ ((double)b[k++] * splicetab[n]);
- if(k >= dz->buflen) {
- b = dz->sampbuf[!bufno];
- k = 0;
- }
- }
- } else {
- for(n=0;n<remain;n++) {
- for(m=0;m<chans;m++)
- obuf[j++] = 0.0;
- }
- for(n=0;n<splicelen;n++) {
- for(m=0;m<chans;m++)
- obuf[j++] = (float) /*round*/ ((double)(b[k++] * n)/(double)splicelen);
- if(k >= dz->buflen) {
- b = dz->sampbuf[!bufno];
- k = 0;
- }
- }
- }
- return(FINISHED);
- }
- /**************************** STORE_DN_HALFSPLICE ***************************
- *
- * GIVE IT bufno where splice STARTS!!!
- */
- int store_dn_halfsplice(int start,int bufno,int chans,int splicelen,dataptr dz)
- {
- int n, k = start, j = 0;
- int m;
- float *b = dz->sampbuf[bufno];
- float *obuf = dz->extrabuf[0];
- double *splicetab = dz->parray[GR_SPLICETAB];
- int true_halfsplice = dz->iparam[GR_SPLICELEN]/2;
- int remain = true_halfsplice - splicelen;
- if(remain < 0) {
- sprintf(errstr,"Invalid splicelen: store_dn_halfsplice()\n");
- return(PROGRAM_ERROR);
- } else if(remain==0) {
- for(n=splicelen-1;n>=0;n--) {
- for(m=0;m<chans;m++)
- obuf[j++] = (float) /*round*/ ((double)b[k++] * splicetab[n]);
- if(k >= dz->buflen) {
- b = dz->sampbuf[!bufno];
- k = 0;
- }
- }
- } else {
- for(n=splicelen-1;n>=0;n--) {
- for(m=0;m<chans;m++)
- obuf[j++] = (float) /*round*/ ((double)(b[k++] * n)/(double)splicelen);
- if(k >= dz->buflen) {
- b = dz->sampbuf[!bufno];
- k = 0;
- }
- }
- for(n=0;n<remain;n++) {
- for(m=0;m<chans;m++)
- obuf[j++] = 0.0;
- }
- }
- return(FINISHED);
- }
- /**************************** COPY_MIDGRAIN_TO_STORE ***************************/
- int copy_midgrain_to_store
- (int mid_grainlen,int bufno,int storelen,int grainstart,int *storepos,int crosbuf,int storeno,dataptr dz)
- {
- float *b, *b2;
- int /* j = *storepos,*/ partbuf, partbuf_samps;
- if(mid_grainlen + *storepos > storelen) {
- sprintf(errstr,"Buffer anomaly: copy_midgrain_to_store()\n");
- return(PROGRAM_ERROR);
- }
- if(crosbuf) {
- if(grainstart + mid_grainlen <= dz->buflen) {
- b2 = dz->sampbuf[!bufno] + grainstart;
- b = dz->extrabuf[storeno] + *storepos;
- memmove((char *)b,(char *)b2,mid_grainlen * sizeof(float));
- *storepos += mid_grainlen;
- } else {
- partbuf = dz->buflen - grainstart;
- partbuf_samps = partbuf;
- b2 = dz->sampbuf[!bufno] + grainstart;
- b = dz->extrabuf[storeno] + *storepos;
- memmove((char *)b,(char *)b2,partbuf_samps * sizeof(float));
- *storepos += partbuf;
- partbuf = mid_grainlen - partbuf;
- partbuf_samps = partbuf;
- b2 = dz->sampbuf[bufno];
- b = dz->extrabuf[storeno] + *storepos;
- memmove((char *)b,(char *)b2, partbuf_samps * sizeof(float));
- *storepos += partbuf;
- }
- } else {
- b2 = dz->sampbuf[bufno] + grainstart;
- b = dz->extrabuf[storeno] + *storepos;
- memmove((char *)b,(char *)b2,mid_grainlen * sizeof(float));
- *storepos += mid_grainlen;
- }
- return(FINISHED);
- }
- /**************************** STORE_UPSPLICE_OF_NEXT_GRAIN ***************************/
- int store_upsplice_of_next_grain(int ibufpos,int bufno,int abs_halfsplice,int chans,dataptr dz)
- {
- int splicestart_bufno = bufno;
- int halfsplice = abs_halfsplice/chans;
- int splicestart = ibufpos - abs_halfsplice;
- if(splicestart < 0) {
- splicestart += dz->buflen;
- splicestart_bufno = !bufno;
- }
- return store_up_halfsplice(1,splicestart,splicestart_bufno,chans,halfsplice,dz);
- }
- /**************************** PUT_GRAIN_INTO_STORE ***************************/
- int put_grain_into_store
- (int is_last_grain,int ibufpos,int bufno,int grainstart,int crosbuf,int chans,int graincnt,dataptr dz)
- {
- if(is_last_grain)
- return copy_last_grain_to_buf(ibufpos,bufno,grainstart,crosbuf,chans,graincnt,dz);
- return copy_grain_to_buf(ibufpos,bufno,grainstart,crosbuf,chans,graincnt,dz);
- }
- /**************************** SAVE_ABS_SAMPLETIME_OF_GRAIN ***************************/
- int save_abs_sampletime_of_grain(int grainstart,int *graincnt,int crosbuf,dataptr dz)
- {
- int samps_read_before_thisbuf = dz->total_samps_read - dz->ssampsread;
- dz->lparray[GR_ABS_POS][*graincnt] = grainstart + samps_read_before_thisbuf;
- if(crosbuf)
- dz->lparray[GR_ABS_POS][*graincnt] -= dz->buflen;
- (*graincnt)++;
- if(*graincnt >= dz->iparam[GR_ARRAYSIZE]) {
- dz->iparam[GR_ARRAYSIZE] += BIGARRAY;
- if((dz->lparray[GR_ABS_POS] =
- (int *)realloc(dz->lparray[GR_ABS_POS],dz->iparam[GR_ARRAYSIZE] * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to enlarge positions store.\n");
- return(MEMORY_ERROR);
- }
- }
- return(FINISHED);
- }
- /**************************** DO_THE_REVERSING_PROCESS ***************************/
- int do_the_reversing_process(int graincnt,int *obufposition,int chans,dataptr dz)
- {
- int exit_status;
- int obufpos = 0, seeksamps = 0, n, seekbufs = 0;
- int abs_splicelen = dz->iparam[GR_ABS_SPLICELEN];
- int abs_halfsplice = abs_splicelen/2;
- int halfsplice = abs_halfsplice/chans;
- int *grainpos;
- if((exit_status = insert_EOF_sampletime_in_samptime_list(graincnt,dz))<0)
- return(exit_status);
- grainpos = dz->lparray[GR_ABS_POS];
- for(n=0;n<graincnt;n++) /* adjust all grain-times to include start of splice */
- grainpos[n] -= abs_halfsplice;
- adjust_for_last_grain(&graincnt,grainpos,dz);
- if((exit_status = clear_outbuf(dz))<0)
- return(exit_status);
- //TW UPDATE
- /* AUGUST 2002 : go back to start of source and read first buffer (to reset dz->ssampsread) */
- if(sndseekEx(dz->ifd[0],0,0) < 0) {
- sprintf(errstr,"seek error at start of do_the_reversing_process()\n");
- return(SYSTEM_ERROR);
- }
- if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
- return(exit_status);
-
- if((exit_status = do_seek_and_read(&seekbufs,&seeksamps,graincnt-1,dz))<0)
- return(exit_status); /* seek to a buffer containing (WHOLE) final grain */
- for(n=graincnt-1;n>=0;n--) {
- if((exit_status = output_whole_grain
- (n,&obufpos,&seeksamps,&seekbufs,halfsplice,abs_splicelen,chans,dz))<0)
- return(exit_status);
- }
- *obufposition = obufpos;
- return(FINISHED);
- }
- /**************************** DO_SEEK_AND_READ ***************************/
- int do_seek_and_read(int *seekbufs,int *seeksamps,int grainno,dataptr dz)
- {
- int exit_status;
- int new_seekbufs = dz->lparray[GR_ABS_POS][grainno]/dz->buflen;
- if(new_seekbufs != *seekbufs) {
- *seekbufs = new_seekbufs;
- if((sndseekEx(dz->ifd[0],(*seekbufs) * dz->buflen,0))<0) {
- sprintf(errstr,"seek error in do_seek_and_read()\n");
- return(SYSTEM_ERROR);
- }
- if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
- return(exit_status);
- *seeksamps = *seekbufs * dz->buflen;
- }
- return(FINISHED);
- }
- /**************************** OUTPUT_UP_HALFSPLICE ****************************/
- int output_up_halfsplice(int *ibufpos,int *obufpos,int chans,int splicelen,int *crosbuf,dataptr dz)
- {
- int exit_status;
- int n, remain;
- int m;
- float *b = dz->sampbuf[0];
- float *obuf = dz->sampbuf[2];
- int i = *ibufpos;
- int j = *obufpos;
- double *splicetab = dz->parray[GR_SPLICETAB];
- int true_halfsplice = dz->iparam[GR_SPLICELEN]/2;
- if((remain = true_halfsplice - splicelen)<0) {
- sprintf(errstr,"Invalid splicelen in output_up_halfsplice()\n");
- return(PROGRAM_ERROR);
- } else if(remain==0) {
- for(n=0;n<splicelen;n++) {
- for(m=0;m<chans;m++)
- obuf[j++] = (float) /*round*/((double)b[i++] * splicetab[n]);
- if((exit_status = test_buffer_overflows(obuf,&j,&i,n,splicelen-1,crosbuf,dz))<0)
- return(exit_status);
- }
- } else {
- for(n=0;n<remain;n++) {
- for(m=0;m<chans;m++)
- obuf[j++] = 0;
- if(j >= dz->buflen) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- j = 0;
- }
- }
- for(n=0;n<splicelen;n++) {
- for(m=0;m<chans;m++)
- obuf[j++] = (float) /*round*/ ((double)(b[i++] * n)/(double)splicelen);
- if((exit_status = test_buffer_overflows(obuf,&j,&i,n,splicelen-1,crosbuf,dz))<0)
- return(exit_status);
- }
- }
- *ibufpos = i;
- *obufpos = j;
- return(FINISHED);
- }
- /**************************** OUTPUT_DN_HALFSPLICE ****************************/
- int output_dn_halfsplice(int *ibufpos,int *obufpos,int chans,int splicelen,int *crosbuf,dataptr dz)
- {
- int exit_status;
- int n, k, remain;
- int m;
- float *b = dz->sampbuf[0];
- float *obuf = dz->sampbuf[2];
- int i = *ibufpos;
- int j = *obufpos;
- double *splicetab = dz->parray[GR_SPLICETAB];
- int true_halfsplice = dz->iparam[GR_SPLICELEN]/2;
- if((remain = true_halfsplice - splicelen)<0) {
- sprintf(errstr,"Invalid splicelen in output_dn_halfsplice()\n");
- return(PROGRAM_ERROR);
- } else if(remain==0) {
- for(n=splicelen-1,k=0;n>=0;n--,k++) {
- for(m=0;m<chans;m++)
- obuf[j++] = (float) /*round */((double)b[i++] * splicetab[n]);
- if((exit_status = test_buffer_overflows(obuf,&j,&i,k,splicelen-1,crosbuf,dz))<0)
- return(exit_status);
- }
- } else {
- for(n=splicelen-1,k=0;n>=0;n--,k++) {
- for(m=0;m<chans;m++)
- obuf[j++] = (float) /*round*/ ((double)(b[i++] * n)/(double)splicelen);
- if((exit_status = test_buffer_overflows(obuf,&j,&i,k,splicelen-1,crosbuf,dz))<0)
- return(exit_status);
- }
- for(n=0;n<remain;n++) {
- for(m=0;m<chans;m++)
- obuf[j++] = 0;
- if(j >= dz->buflen) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- j = 0;
- }
- }
- }
- *ibufpos = i;
- *obufpos = j;
- return(FINISHED);
- }
- /**************************** DO_IN_SITU_HALFSPLICE_ON_STORED_GRAIN ****************************/
- int do_in_situ_halfsplice_on_stored_grain(int bufpos,int chans,int splicelen,int grainstorelen,dataptr dz)
- {
- int n, k, remain;
- int m;
- float *obuf = dz->extrabuf[2];
- double *splicetab = dz->parray[GR_SPLICETAB];
- int true_halfsplice = dz->iparam[GR_SPLICELEN]/2;
- int abs_halfsplice = true_halfsplice * chans;
- if(bufpos + abs_halfsplice > grainstorelen) {
- sprintf(errstr,"Grainstore buffer overflow: do_in_situ_halfsplice_on_stored_grain()\n");
- return(PROGRAM_ERROR);
- }
- if((remain = true_halfsplice - splicelen)<0) {
- sprintf(errstr,"Invalid splicelen in do_in_situ_halfsplice_on_stored_grain()\n");
- return(PROGRAM_ERROR);
- } else if(remain==0) {
- for(n=splicelen-1,k=0;n>=0;n--,k++) {
- for(m=0;m<chans;m++) {
- obuf[bufpos] = (float) /*round*/((double)obuf[bufpos] * splicetab[n]);
- bufpos++;
- }
- }
- } else {
- for(n=splicelen-1,k=0;n>=0;n--,k++) {
- for(m=0;m<chans;m++) {
- obuf[bufpos] = (float) /*round*/ ((double)(obuf[bufpos] * n)/(double)splicelen);
- bufpos++;
- }
- }
- for(n=0;n<remain;n++) {
- for(m=0;m<chans;m++)
- obuf[bufpos++] = 0.0;
- }
- }
- return(FINISHED);
- }
- /**************************** TEST_BUFFER_OVERFLOWS ****************************/
- int test_buffer_overflows(float *obuf,int *obufpos,int *ibufpos,int n,int maxlen,int *crosbuf,dataptr dz)
- {
- int exit_status;
- if(*obufpos >= dz->buflen) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- *obufpos = 0;
- }
- if(*ibufpos >= dz->ssampsread && n < maxlen) {
- if(*crosbuf) {
- sprintf(errstr,"double crosbuf: test_buffer_overflows()\n");
- return(PROGRAM_ERROR);
- }
- if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
- return(exit_status);
- *crosbuf = TRUE;
- *ibufpos = 0;
- }
- return(FINISHED);
- }
- /**************************** COPY_MIDGRAIN_TO_OUTPUT ***************************/
- int copy_midgrain_to_output(int mid_grainlen,int *ibufpos,int *obufpos,int *crosbuf,int chans,dataptr dz)
- {
- int exit_status;
- int n;
- int m;
- float *b = dz->sampbuf[0], *obuf = dz->sampbuf[2];
- int i = *ibufpos;
- int j = *obufpos;
- mid_grainlen /= chans;
- for(n=0; n<mid_grainlen;n++) {
- for(m=0;m<chans;m++)
- obuf[j++] = b[i++];
- if((exit_status = test_buffer_overflows(obuf,&j,&i,n,mid_grainlen-1,crosbuf,dz))<0)
- return(exit_status);
- }
- *obufpos = j;
- *ibufpos = i;
- return(FINISHED);
- }
- /**************************** INSERT_EOF_SAMPLETIME_IN_SAMPTIME_LIST ***************************/
- int insert_EOF_sampletime_in_samptime_list(int graincnt,dataptr dz)
- {
- if(graincnt+1 > dz->iparam[GR_ARRAYSIZE]) {
- if((dz->lparray[GR_ABS_POS] =
- (int *)realloc(dz->lparray[GR_ABS_POS],(graincnt+1) * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to enlarge positions store.\n");
- return(MEMORY_ERROR);
- }
- }
- dz->lparray[GR_ABS_POS][graincnt] = dz->insams[0];
- return(FINISHED);
- }
- /**************************** ADJUST_FOR_LAST_GRAIN ***************************/
- void adjust_for_last_grain(int *graincnt,int *grainpos,dataptr dz)
- {
- int lastgap;
- if(dz->vflag[LOSE_LAST_GRAIN]) /* get rid of last grain if flagged */
- (*graincnt)--;
- else if((lastgap = grainpos[*graincnt] - grainpos[(*graincnt)-1]) < dz->iparam[GR_ABS_SPLICELEN]) {
- fprintf(stdout,"WARNING: Loosing last grain: too short.\n");
- fflush(stdout);
- (*graincnt)--;
- } else if(lastgap > dz->buflen) { /* truncate last grain if too int */
- fprintf(stdout,"WARNING: Last grain truncated: too int.\n");
- fflush(stdout);
- grainpos[*graincnt] = grainpos[(*graincnt)-1] + dz->buflen;
- }
- }
- /**************************** CLEAR_OUTBUF ***************************/
- int clear_outbuf(dataptr dz)
- {
- memset((char *)dz->sampbuf[2],0,dz->buflen * sizeof(float));
- return(FINISHED);
- }
- /**************************** OUTPUT_WHOLE_GRAIN ***************************/
- int output_whole_grain(int n,int *obufpos,int *seeksamps,int *seekbufs,
- int halfsplice,int abs_splicelen,int chans,dataptr dz)
- {
- int exit_status;
- int crosbuf = FALSE;
- int ibufpos;
- int mid_grainlen;
- int startsplice;
- int endsplice;
- startsplice = endsplice = halfsplice;
- if((ibufpos = dz->lparray[GR_ABS_POS][n] - *seeksamps)<0) { /* IF current grain NOT in current buffer */
- if(*seeksamps==0) { /* IF at start of file */
- if((exit_status = adjust_firstgrain_upsplice(&ibufpos,&startsplice,n,chans))<0)
- return(exit_status);
- } else { /* ELSE: change current buffer */
- if((exit_status = do_seek_and_read(seekbufs,seeksamps,n,dz))<0)
- return(exit_status);
- ibufpos = dz->lparray[GR_ABS_POS][n] - *seeksamps;
- }
- }
- if((exit_status = output_up_halfsplice(&ibufpos,obufpos,chans,startsplice,&crosbuf,dz))<0)
- return(exit_status);
- mid_grainlen = (dz->lparray[GR_ABS_POS][n+1] - dz->lparray[GR_ABS_POS][n]) - abs_splicelen;
- if(crosbuf) {
- (*seekbufs)++;
- (*seeksamps) += dz->buflen;
- }
- crosbuf = FALSE;
- if(mid_grainlen > 0) {
- if((exit_status = copy_midgrain_to_output(mid_grainlen,&ibufpos,obufpos,&crosbuf,chans,dz))<0)
- return(exit_status);
- if(crosbuf) {
- (*seekbufs)++;
- (*seeksamps) += dz->buflen;
- }
- }
- crosbuf = FALSE;
- if((exit_status = output_dn_halfsplice(&ibufpos,obufpos,chans,endsplice,&crosbuf,dz))<0)
- return(exit_status);
- if(crosbuf) {
- (*seekbufs)++;
- (*seeksamps) += dz->buflen;
- }
- return(FINISHED);
- }
- /**************************** ADJUST_FIRSTGRAIN_UPSPLICE ***************************/
- int adjust_firstgrain_upsplice(int *ibufpos,int *startsplice,int n,int chans)
- {
- if(n!=0) { /* MUST be 1st grain */
- sprintf(errstr,"Grain accounting error: adjust_firstgrain_upsplice()\n");
- return(PROGRAM_ERROR);
- }
- *startsplice += *ibufpos/chans; /* shorten startsplice by deficit of [stereo] samples */
- *ibufpos = 0; /* reset output read to start of file */
- return(FINISHED);
- }
- /************************* DO_GRAIN_REPITCHING *************************/
- /* RWD 4:2002 : NB modified to allow n-channels */
- int do_grain_repitching(int *actual_grainlen,int bufno,int grainstart,int new_grainlen,int orig_grainlen,
- int chans,int crosbuf,double pichratio,dataptr dz)
- {
- int exit_status;
- int m;
- int k = 0, here, thishere;
- double dpoint = 0.0, frac;
- //TW CHANGED
- // float /*thisval[2],*/ nextval[2], diff[2];
- float /*thisval[2],*/ nextval, diff;
- float *b, *b2, *grainbuf = dz->extrabuf[2];
- float *thisval;
- thisval = (float *) malloc(chans * sizeof(float));
- if(thisval==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to enlarge positions store.\n");
- return MEMORY_ERROR;
- }
- if(crosbuf)
- b = dz->sampbuf[!bufno];
- else
- b = dz->sampbuf[bufno];
- orig_grainlen /= chans;
- while(k < new_grainlen) {
- here = (int)dpoint; /* truncate */
- frac = dpoint - (double)here;
- thishere = (here*chans);
- thishere += grainstart;
- if((exit_status = test_for_bufcros(&thishere,&b,bufno,crosbuf,dz))<0) {
- free(thisval);
- return(exit_status);
- }
- if(exit_status == TRUE) /* changed buffer */
- grainstart -= dz->buflen;
- for(m=0;m<chans;m++)
- thisval[m] = b[thishere+m];
- b2 = b;
- here++;
- thishere = (here*chans);
- thishere += grainstart;
- if((exit_status = test_for_bufcros(&thishere,&b2,bufno,crosbuf,dz))<0) {
- free(thisval);
- return(exit_status);
- }
- for(m=0;m<chans;m++) {
- //TW MODIFIED
- nextval = b2[thishere+m];
- diff = nextval - thisval[m];
- grainbuf[k++] = (float) /*round*/(((double)diff * frac) + thisval[m]);
- }
- if((dpoint += pichratio) > orig_grainlen)
- break;
- }
- *actual_grainlen = k;
- free(thisval);
- return(FINISHED);
- }
- /************************* TEST_FOR_BUFCROS *************************/
- int test_for_bufcros(int *thishere,float **b,int bufno,int crosbuf,dataptr dz)
- {
- if(*thishere >= dz->buflen) {
- if(crosbuf==FALSE) {
- sprintf(errstr,"Buffer accounting problem: test_for_bufcros()\n");
- return(PROGRAM_ERROR);
- }
- *b = dz->sampbuf[bufno];
- *thishere -= dz->buflen;
- return(TRUE);
- }
- return(FALSE);
- }
- /************************* SAVE_NEXTGRAIN_UPSPLICE_ELSEWHERE *************************/
- int save_nextgrain_upsplice_elsewhere
- (int ibufpos,int bufno,int abs_halfsplice,int halfsplice,int chans,dataptr dz)
- {
- int splicestart_bufno = bufno;
- int start_splice = ibufpos - abs_halfsplice;
- if(start_splice < 0) {
- splicestart_bufno = !bufno;
- start_splice += dz->buflen;
- }
- return store_up_halfsplice(0,start_splice,splicestart_bufno,chans,halfsplice,dz);
- }
- /************************* COPYGRAIN_FROM_GRAINBUF_TO_OUTBUF *************************/
- int copygrain_from_grainbuf_to_outbuf(int *obufpos,int grainlen,dataptr dz)
- {
- int exit_status;
- int remain = dz->buflen - *obufpos;
- float *there = dz->sampbuf[2] + *obufpos;
- float *here = dz->extrabuf[2];
- while(grainlen >= remain) {
- memmove((char *)there,(char *)here,remain * sizeof(float));
- if((exit_status = write_samps(dz->sampbuf[2],dz->buflen,dz))<0)
- return(exit_status);
- *obufpos = 0;
- there = dz->sampbuf[2];
- here += remain;
- grainlen -= remain;
- remain = dz->buflen;
- }
- if(grainlen) {
- memmove((char *)there,(char *)here,grainlen * sizeof(float));
- *obufpos += grainlen;
- }
- return(FINISHED);
- }
- /************************* RETRIEVE_UPSPLICE_FOR_NEXTGRAIN *************************/
- int retrieve_upsplice_for_nextgrain(int abs_halfsplice,dataptr dz)
- {
- memmove((char *)dz->extrabuf[1],(char *)dz->extrabuf[0],abs_halfsplice * sizeof(float));
- return(FINISHED);
- }
- /************************* RETIME_MAIN_BODY_OF_GRAIN *************************/
- //TW REVISED
- int retime_main_body_of_grain(int grainstart,int bufno,double pichratio,
- double timeratio,int chans,int crosbuf,int *grainadjusted,
- int orig_grainlen,int *new_grainlen,dataptr dz)
- {
- int exit_status;
- int abs_splicelen = dz->iparam[GR_ABS_SPLICELEN];
- int abs_halfsplice = abs_splicelen/2; /* guaranteed to fall on stereo boundary */
- int halfsplice = dz->iparam[GR_SPLICELEN]/2;
- *new_grainlen = round((double)(orig_grainlen/chans) * timeratio) * chans;
- if(*new_grainlen < dz->iparam[GR_ABS_SPLICEX2]) {
- *new_grainlen = dz->iparam[GR_ABS_SPLICEX2];
- (*grainadjusted)++;
- }
- *new_grainlen -= abs_halfsplice;
- orig_grainlen -= abs_halfsplice;
- if((exit_status = repitch_main_body_of_grain(bufno,grainstart,*new_grainlen,orig_grainlen,
- pichratio,chans,crosbuf,halfsplice,abs_halfsplice,dz))<0)
- return(exit_status);
- return(FINISHED);
- }
- /************************* REPITCH_MAIN_BODY_OF_GRAIN *************************/
- int repitch_main_body_of_grain(int bufno,int grainstart,int new_grainlen,int orig_grainlen,
- double pichratio,int chans,int crosbuf,int halfsplice,int abs_halfsplice,dataptr dz)
- {
- int exit_status;
- int actual_grainlen;
- int splicelen;
- int splicestart;
- float *grainbuf;
- if(new_grainlen > dz->iparam[GR_STORESIZE]) {
- if((dz->extrabuf[2] = (float *)realloc(dz->extrabuf[2],new_grainlen * sizeof(float)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to enlarge grain store.\n");
- return(MEMORY_ERROR);
- }
- dz->iparam[GR_STORESIZE] = (int)new_grainlen;
- }
- grainbuf = dz->extrabuf[2];
- memset((char *)grainbuf,0,new_grainlen * sizeof(float));
- if((exit_status = do_grain_repitching
- (&actual_grainlen,bufno,grainstart,new_grainlen,orig_grainlen,chans,crosbuf,pichratio,dz))<0)
- return(exit_status);
- splicelen = halfsplice;
- splicestart = actual_grainlen - abs_halfsplice;
- if(splicestart < 0) {
- splicelen += splicestart/chans;
- splicestart = 0;
- }
- return do_in_situ_halfsplice_on_stored_grain(splicestart,chans,splicelen,new_grainlen,dz);
- }
- /************************* CREATE_REPITCHED_AND_RETIMED_GRAIN *************************/
- //TW REVISED
- int create_repitched_and_retimed_grain
- (int bufno,int grainstart,int orig_grainlen,int *new_grainlen,
- double pichratio,double timeratio,int *obufpos,int *is_first_grain,
- int *grainadjusted,int abs_halfsplice,int chans,int crosbuf,dataptr dz)
- {
- int exit_status;
- if((exit_status = retime_main_body_of_grain(grainstart,bufno,pichratio,timeratio,
- chans,crosbuf,grainadjusted,orig_grainlen,new_grainlen,dz))<0)
- return(exit_status);
- if(!(*is_first_grain)) {
- if((exit_status = read_up_halfsplice(obufpos,abs_halfsplice,dz))<0)
- return(exit_status);
- }
- *is_first_grain = FALSE;
- return copygrain_from_grainbuf_to_outbuf(obufpos,*new_grainlen,dz);
- }
- /************************* SAVE_ORIGGRAIN_LENGTH_AND_STORE_NEXTGRAINS_UPSPLICE *************************/
- int save_origgrain_length_and_store_nextgrains_upsplice(int *orig_grainlen,int ibufpos,int bufno,
- int grainstart,int abs_halfsplice,int halfsplice,int crosbuf,int chans,int is_last_grain,dataptr dz)
- {
- *orig_grainlen = ibufpos - grainstart;
- if(crosbuf)
- *orig_grainlen += dz->buflen;
- if((*orig_grainlen - abs_halfsplice)<0) {
- if(!is_last_grain) {
- sprintf(errstr,"Anomalous too short grain: save_origgrain_length_and_store_nextgrains_upsplice()\n");
- return(PROGRAM_ERROR);
- } else {
- fprintf(stdout,"WARNING: Last grain omitted: too short.\n");
- return(CONTINUE);
- }
- }
- return save_nextgrain_upsplice_elsewhere(ibufpos,bufno,abs_halfsplice,halfsplice,chans,dz);
- }
- /************************* REPITCHING_PROCESS *************************/
- int repitching_process(int ibufpos,int bufno,int grainstart,int abs_halfsplice,int halfsplice,int *graincnt,
- int *obufpos,int *orig_grainlen,int *new_grainlen,int *grainadjusted,
- int *is_first_grain,int is_last_grain,int chans,int crosbuf,dataptr dz)
- {
- int exit_status;
- double timeratio = 1.0, pichratio;
- int n;
- if(*is_first_grain && (exit_status = create_an_upsplice_from_pregrain_material(*obufpos,chans,dz))<0)
- return(exit_status);
- if((exit_status = save_origgrain_length_and_store_nextgrains_upsplice
- (orig_grainlen,ibufpos,bufno,grainstart,abs_halfsplice,halfsplice,crosbuf,chans,is_last_grain,dz))<0)
- return(exit_status);
- if(exit_status==CONTINUE) /* last grain too short */
- return(FINISHED);
- switch(dz->mode) {
- case(GR_REPEATS):
- for(n=0;n<dz->iparam[GR_RATIOCNT];n++) {
- pichratio = dz->parray[GR_RATIO][n];
- if((exit_status = create_repitched_and_retimed_grain
- (bufno,grainstart,*orig_grainlen,new_grainlen,pichratio,timeratio,obufpos,
- is_first_grain,grainadjusted,abs_halfsplice,chans,crosbuf,dz))<0)
- return(exit_status);
- }
- break;
- case(GR_NO_REPEATS):
- pichratio = dz->parray[GR_RATIO][*graincnt];
- if((exit_status = create_repitched_and_retimed_grain
- (bufno,grainstart,*orig_grainlen,new_grainlen,pichratio,timeratio,obufpos,
- is_first_grain,grainadjusted,abs_halfsplice,chans,crosbuf,dz))<0)
- return(exit_status);
- if(++(*graincnt)>=dz->iparam[GR_RATIOCNT])
- *graincnt = 0;
- break;
- default:
- sprintf(errstr,"Unknown case: repitching_process()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- /************************* REPITCHING_AND_RETIMING_PROCESS *************************/
- int repitching_and_retiming_process(int ibufpos,int bufno,int grainstart,int abs_halfsplice,
- int halfsplice,int *graincnt,int *obufpos,int *orig_grainlen,int *new_grainlen,int *grainadjusted,
- int *is_first_grain,int is_last_grain,int chans,int crosbuf,dataptr dz)
- {
- int exit_status;
- double timeratio, pichratio;
- int n;
- if(*is_first_grain && (exit_status = create_an_upsplice_from_pregrain_material(*obufpos,chans,dz))<0)
- return(exit_status);
- if((exit_status = save_origgrain_length_and_store_nextgrains_upsplice
- (orig_grainlen,ibufpos,bufno,grainstart,abs_halfsplice,halfsplice,crosbuf,chans,is_last_grain,dz))<0)
- return(exit_status);
- if(exit_status==CONTINUE) /* last grain too short */
- return(FINISHED);
- switch(dz->mode) {
- case(GR_REPEATS):
- for(n=0;n<dz->iparam[GR_RATIOCNT];n+=2) {
- pichratio = dz->parray[GR_RATIO][n];
- timeratio = dz->parray[GR_RATIO][n+1];
- if((exit_status = create_repitched_and_retimed_grain
- (bufno,grainstart,*orig_grainlen,new_grainlen,pichratio,timeratio,obufpos,
- is_first_grain,grainadjusted,abs_halfsplice,chans,crosbuf,dz))<0)
- return(exit_status);
- }
- break;
- case(GR_NO_REPEATS):
- pichratio = dz->parray[GR_RATIO][(*graincnt)++];
- timeratio = dz->parray[GR_RATIO][(*graincnt)++];
- if((exit_status = create_repitched_and_retimed_grain
- (bufno,grainstart,*orig_grainlen,new_grainlen,pichratio,timeratio,obufpos,
- is_first_grain,grainadjusted,abs_halfsplice,chans,crosbuf,dz))<0)
- return(exit_status);
- if(*graincnt >= dz->iparam[GR_RATIOCNT])
- *graincnt = 0;
- break;
- default:
- sprintf(errstr,"Unknown case: repitching_and_retiming_process()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- /****************************** TIMESTRETCH_ITERATIVE ****************************/
- int timestretch_iterative(dataptr dz)
- {
- int exit_status, do_slow = 0, do_regu;
- float *ibuf = dz->sampbuf[0];
- float *obuf = dz->sampbuf[1];
- // double *peak = dz->parray[0];
- int *pos = dz->lparray[0];
- int peakcnt, startsearch, endsearch, local_minima_cnt, minimum_element_len;
- int stretchable_len, required_segsection_len, total_segsection_length;
- int element_cnt, max_elements_needed;
- int arrsiz, fullperms, patternsize;
- int *pattern;
- int finished;
- int n, k=0, outpos, startseg, startpos, endpos, seglen;
- int abspos, new_abspos;
- int ascatter = 0, pscatter = 0, jitter = 0;
- double gain = 1.0, trans = 1.0, d, part, time, diff;
- float val, nextval;
- double z = (dz->param[RRR_END] - dz->param[RRR_START]) * dz->param[RRR_REPET];
- double starttime_of_iter, davg_step;
- int total_slolen, total_slo_incr, slo_incr, min_step, j, avg_step, gap, maxsamp = 0;
- int *seg_step = NULL, *seg_len = NULL;
- int thiselementcnt, regusegscnt, okcnt, *seg_ok = NULL;
- if(dz->vflag[0] == 0)
- z += dz->param[RRR_START];
- if(dz->vflag[1] == 0)
- z += dz->duration - dz->param[RRR_END];
- //2010
- dz->tempsize = (int)round(z * dz->infile->srate) * dz->infile->channels;
- fprintf(stdout,"INFO: Generating output.\n");
- fflush(stdout);
- if(sloom)
- display_virtual_time(0,dz);
- if(dz->brksize[RRR_ASCAT] || !flteq(dz->param[RRR_ASCAT],0.0)) {
- ascatter = 1;
- jitter = 1;
- }
- if(dz->brksize[RRR_PSCAT] || !flteq(dz->param[RRR_PSCAT],0.0)) {
- pscatter = 1;
- jitter = 1;
- }
- if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
- return(exit_status);
- dz->sampbuf[0][dz->insams[0]] = dz->sampbuf[0][dz->insams[0] - 1]; /* wrap around point for interpolation */
- startsearch = (int)round(dz->param[RRR_START] * dz->infile->srate);
- endsearch = (int)round(dz->param[RRR_END] * dz->infile->srate);
- /* FIND ALL POSITIVE PEAKS : always look only at +ve vals, so all zero-crossings eventually found will be from +ve to -ve */
- peakcnt = 0;
- if((exit_status = find_all_positive_peaks(startsearch,endsearch,&peakcnt,dz)) < 0)
- return(exit_status);
- /* FIND ALL POSITIVE-PEAK MINIMA : overwriting the arrays peak-vals & peak-position with minima-vals & minima-positions */
- local_minima_cnt = 0;
- if((exit_status = find_all_local_minima(peakcnt,&local_minima_cnt,dz)) < 0)
- return(exit_status);
- /* ELIMINATE SPURIOUS MINIMA */
- if((exit_status = eliminate_spurious_minima(&local_minima_cnt,&minimum_element_len,dz)) < 0)
- return (exit_status);
- fprintf(stdout,"INFO: Original number of segments found = %d\n",local_minima_cnt - 1);
- fflush(stdout);
- /* CHECK MINIMA FOUND AGAINST INPUT ESTIMATE */
- if((local_minima_cnt - 1) >= 2 * dz->iparam[RRR_GET]) {
- if((exit_status = eliminate_excess_minima(&local_minima_cnt,pos,dz)) < 0)
- return (exit_status);
- fprintf(stdout,"INFO: Reduced to = %d\n",local_minima_cnt - 1);
- fflush(stdout);
- }
- /* SEARCH FOR ZERO CROSSINGS AFTER MINIMA */
- if((exit_status = locate_zero_crossings(local_minima_cnt,dz)) < 0)
- return (exit_status);
- /* CALCULATE HOW int STRETCHED SECTION SHOULD BE */
- stretchable_len = pos[local_minima_cnt-1] - pos[0];
- required_segsection_len = (int)round((double)stretchable_len * dz->param[RRR_STRETCH]);
- /* CALCULATE HOW MANY ELEMENTS TO USE */
- element_cnt = local_minima_cnt - 1;
- max_elements_needed = (int)round(ceil((double)required_segsection_len/(double)minimum_element_len));
- max_elements_needed *= 2; /* required no of elements is set to a value greater than possibly required */
- /* CALCULATE HOW MANY PERMUTATIONS NEEDED */
- arrsiz = element_cnt * dz->iparam[RRR_REPET]; /* if elements can be repeated N times, perm-array can contain N copies of values */
- fullperms = max_elements_needed / arrsiz;
- if(fullperms * arrsiz < max_elements_needed) /* total number of permutations to generate must include any part permutation */
- fullperms++;
- patternsize = fullperms * arrsiz;
- if((pattern = (int *)malloc(patternsize * sizeof(int)))==NULL) {
- sprintf(errstr,"Insufficient memory to generate segment permutation.\n");
- return(MEMORY_ERROR);
- }
- /* GENERATE RANDOM PATTERN */
- if((exit_status = rand_ints_with_restricted_repeats(element_cnt,max_elements_needed,arrsiz,fullperms,&pattern,dz)) < 0)
- return(exit_status);
- if(dz->brksize[RRR_SLOW]) {
- maxsamp = (int)round(dz->maxtime * (double)dz->infile->srate);
- if((seg_step = (int *)malloc(element_cnt * sizeof(int)))==NULL) {
- sprintf(errstr,"Insufficient memory to store steps between segment if slowed.\n");
- return(MEMORY_ERROR);
- }
- if(dz->brksize[RRR_REGU]) {
- if((seg_len = (int *)malloc(element_cnt * sizeof(int)))==NULL) {
- sprintf(errstr,"Insufficient memory to store orig segment lengths, if slowed.\n");
- return(MEMORY_ERROR);
- }
- if((seg_ok = (int *)malloc(element_cnt * sizeof(int)))==NULL) {
- sprintf(errstr,"Insufficient memory to store segment flags, if regularised.\n");
- return(MEMORY_ERROR);
- }
- }
- }
- /* COPY SOUND START TO OUTBUF */
- outpos = 0;
- if(dz->vflag[0] == 0) {
- memcpy((char *)obuf,(char *)ibuf,pos[0] * sizeof(float));
- outpos = pos[0];
- }
- /* GENERATE OUTPUT SEQUENCE OF ELEMENTS */
- total_segsection_length = 0;
- finished = 0;
- time = 0.0;
- abspos = dz->total_samps_written + outpos;
- if(dz->brksize[RRR_SLOW])
- maxsamp += abspos;
- starttime_of_iter = (double)abspos/(double)dz->infile->srate;
- do {
- for(n=0; n < patternsize; n++) {
- if(n % element_cnt == 0) {
- do_slow = 0;
- do_regu = 0;
- if(dz->brksize[RRR_SLOW]) {
- time = (double)abspos/(double)dz->infile->srate;
- time -= starttime_of_iter;
- if((exit_status = read_value_from_brktable(time,RRR_SLOW,dz))<0)
- return(exit_status);
- if(dz->brksize[RRR_REGU] > 0) {
- if((exit_status = read_value_from_brktable(time,RRR_REGU,dz))<0)
- return(exit_status);
- }
- }
- if(dz->param[RRR_SLOW] > 1.0) { // If segments are to be slowed (by intervening silence)
- do_slow = 1;
- while(do_slow) {
- thiselementcnt = min(element_cnt,patternsize-n); // SAFETY (should be whole number of element_cnts in patternsize)
- total_slolen = (int)round(stretchable_len * dz->param[RRR_SLOW]); // Sample duration of all segs, once slowed by intervening gaps
- total_slo_incr = total_slolen - stretchable_len; // Total added silence, in samples
- slo_incr = (int)round((double)total_slo_incr/(double)thiselementcnt); // Silence to be inserted after to each element
- if(slo_incr <= 0) {
- do_slow = 0;
- break;
- } // Regularisation of rhythm of output cannot be done until there is
- if(dz->param[RRR_REGU] > 0.0) { // maniupulable silence between segments, which only occues after SLOW applied
- do_regu = 1;
- while(do_regu) {
- total_slo_incr = slo_incr * thiselementcnt; // Total added silence, after accounting for rounding
- min_step = dz->insams[0] + 1;
- avg_step = 0;
- for(j = 0,k=n; j < thiselementcnt;j++,k++){
- startseg = pattern[k];
- startpos = pos[startseg];
- endpos = pos[startseg+1];
- seglen = endpos - startpos;
- seg_len[j] = seglen; // Find actual length of each segment
- seg_step[j] = seg_len[j] + slo_incr; // Find step between start of one seg & next (when intervening silence added) BEFORE REGULARISING
- seg_ok[j] = 1; // Mark as a valid segment to regularise
- min_step = min(min_step,seg_step[j]); // Find the minimim step
- avg_step += seg_step[j]; // Find the average step
- }
- regusegscnt = 0;
- okcnt = thiselementcnt;
- davg_step = (double)avg_step/(double)okcnt; // Once regularised, step between seg entries will be set to the average value
- for(j=0; j < thiselementcnt; j++) { // If length of a segment is > average, this can't be done
- if(seg_len[j] > davg_step) { // So mark any such segment as not valid for the averaging process
- seg_ok[j] = 0;
- avg_step -= seg_len[j]; // and remove it from the calculation of the average step
- okcnt--;
- davg_step = (double)avg_step/(double)okcnt;
- } else
- regusegscnt++; // Count all the averagable segments
- }
- if(regusegscnt < 2) // If less than 2 valid segs, no averaging can be done
- do_regu = 0;
- break;
- }
- if(do_regu) {
- avg_step = (int)round((double)avg_step/(double)regusegscnt);
- for(j=0; j < thiselementcnt; j++) { // For all valid segments
- if(seg_ok[j]) // (partially) adjust step between it and next to the average step
- seg_step[j] = ((int)round((avg_step - seg_step[j]) * dz->param[RRR_REGU])) + seg_step[j];
- }
- }
- }
- break;
- }
- if(do_slow) {
- if(do_regu) {
- for(j=0; j < thiselementcnt; j++) // Find the gap left after each segment
- seg_step[j] -= seg_len[j];
- } else { // If seg_entries NOT to be regularised
- for(j=0; j < thiselementcnt; j++) // Set silent gap between segs all to same val
- seg_step[j] = slo_incr;
- }
- }
- }
- }
- startseg = pattern[n];
- startpos = pos[startseg];
- endpos = pos[startseg+1];
- seglen = endpos - startpos;
- if(jitter) {
- time = (double)abspos/(double)dz->infile->srate;
- if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
- return(exit_status);
- k = startpos;
- d = (double)startpos;
- part = 0.0;
- if(ascatter) { /* generate random value for seg gain, within given range */
- gain = drand48() * dz->param[RRR_ASCAT];
- gain = 1.0 - gain;
- }
- if(pscatter) {
- trans = (drand48() * 2.0) - 1.0;
- if(trans >= 0.0) /* randomly chose up or down transposition */
- trans = 1.0;
- else
- trans = -1.0; /* generate random semitone step within given range */
- trans *= (drand48() * dz->param[RRR_PSCAT]);
- trans /= 12; /* convert to transposition ratio = step in sample-reading */
- trans = pow(2.0,trans);
- }
- while(k < endpos) {
- val = ibuf[k];
- nextval = ibuf[k+1];
- diff = nextval - val;
- z = val + (diff * part);
- z *= gain;
- d += trans;
- k = (int)d; /* TRUNCATE */
- part = d - (double)k;
- obuf[outpos] = (float)z;
- if(++outpos >= dz->buflen) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- outpos = 0;
- }
- }
- } else {
- for(k = startpos; k < endpos; k++) {
- obuf[outpos] = ibuf[k];
- if(++outpos >= dz->buflen) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- outpos = 0;
- }
- }
- }
- new_abspos = dz->total_samps_written + outpos;
- if(do_slow) {
- k = n % element_cnt;
- gap = seg_step[k];
- for(j=0;j<gap;j++) {
- obuf[outpos] = 0;
- if(++outpos >= dz->buflen) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- outpos = 0;
- }
- }
- new_abspos = dz->total_samps_written + outpos;
- }
- abspos = new_abspos;
- // If reach end of slowing curve, but still patterns left, exit pattern generation
- if(dz->brksize[RRR_SLOW] && abspos >= maxsamp)
- finished = 1;
-
- // If reach end of patterns
- if((total_segsection_length += seglen) >= required_segsection_len || (n == patternsize - 1)) { // Should be equivalent!!
- // If not at end of slowing pattern, generate more random perms, and restart loop (n = 0)
-
- if(dz->brksize[RRR_SLOW] && abspos < maxsamp) {
- if((exit_status = rand_ints_with_restricted_repeats(element_cnt,max_elements_needed,arrsiz,fullperms,&pattern,dz)) < 0)
- return(exit_status);
- } else
- finished = 1;
- }
- if(finished)
- break;
- }
- } while(!finished);
- if(!finished) {
- sprintf(errstr,"Insufficient segments generated at output stage.\n");
- return(PROGRAM_ERROR);
- }
- /* COPY SOUND END TO OUTBUF */
- if(dz->vflag[1] == 0) {
- for(n = pos[local_minima_cnt - 1]; n < dz->insams[0];n++) {
- obuf[outpos] = ibuf[n];
- if(++outpos >= dz->buflen) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- /*memset((char *)obuf,0,dz->bigbufsize);*/
- memset(obuf,0,sizeof(float)* dz->buflen); /*RWD ?? */
- outpos = 0;
- }
- }
- }
- if(outpos > 0) {
- if((exit_status = write_samps(obuf,outpos,dz))<0)
- return(exit_status);
- }
- return(FINISHED);
- }
- /****************************** RAND_INTS_WITH_RESTRICTED_REPEATS ****************************/
- int rand_ints_with_restricted_repeats(int element_cnt,int max_elements_needed,int arrsiz,int fullperms,int **pattern,dataptr dz)
- {
- int n, m, i, k=0, j;
- int endcnt, endval, allowed, checkpart;
- int patterncnt = 0;
- int *arr, *arr2, *perm;
- if((arr = (int *)malloc(arrsiz * sizeof(int)))==NULL) {
- sprintf(errstr,"Insufficient memory for permutation array 1.\n");
- return(MEMORY_ERROR);
- }
- if((perm = (int *)malloc(arrsiz * sizeof(int)))==NULL) {
- sprintf(errstr,"Insufficient memory for permutation array 2.\n");
- return(MEMORY_ERROR);
- }
- if((arr2 = (int *)malloc(dz->iparam[RRR_REPET] * sizeof(int)))==NULL) {
- sprintf(errstr,"Insufficient memory for permutation array 3.\n");
- return(MEMORY_ERROR);
- }
- n = 0;
- for(j=0;j<dz->iparam[RRR_REPET];j++) { /* fill array with REPET copies of values. */
- for(i=0;i<element_cnt;i++) /* this set can be permd AS A WHOLE, as repet adjacent copies of any val */
- arr[n++] = i; /* which might arise in perming this set, are allowed */
- }
- endcnt = 0; /* number of items repeated at end of previous perm */
- endval = -1; /* value (possibly repeated) at end of previous perm (for first perm set it to a val not in perm */
- /* initially this is just the 'startval' fixed by the user */
- allowed = dz->iparam[RRR_REPET]; /* number of permissible repetitions of this val at start of 1st perm */
- checkpart = arrsiz - dz->iparam[RRR_REPET]; /* items at end of array to test for repetitions */
- n = 0;
- while(n < fullperms) {
- do_repet_restricted_perm(arr,perm,arrsiz,allowed,endval);
- j = 0;
- for(m = 0;m <arrsiz;m++) {
- (*pattern)[patterncnt] = arr[perm[m]];
- patterncnt++;
- if(m >= checkpart) /* save last checkable stretch of perm */
- arr2[j++] = arr[perm[m]];
- }
- if(n < fullperms -1) {
- j--;
- endval = arr2[j--]; /* note the val at end of perm */
- endcnt = 1; /* and count it */
- for(k = j; k>= 0; k--) {
- if(arr2[k] == endval) /* check adjacent vals, for repetition of value: count */
- endcnt++;
- else /* if no more repetitions, finish counting */
- break;
- }
- allowed = dz->iparam[RRR_REPET] - endcnt; /* get number of permissible repets at start of next perm */
- }
- n++;
- }
- return FINISHED;
- }
- /****************************** DO_REPET_RESTRICTED_PERM ****************************/
- void do_repet_restricted_perm(int *arr, int *perm, int arrsiz, int allowed, int endval)
- {
- int n, t;
- int checklen = allowed + 1;
- int done = 0;
- while(!done) {
- for(n=0;n<arrsiz;n++) {
- t = (int)(drand48() * (double)(n+1)); /* TRUNCATE */
- if(t==n)
- hhprefix(n,arrsiz,perm);
- else
- hhinsert(n,t,arrsiz,perm);
- }
- if(checklen <= 0)
- break;
- for(n=0;n<checklen;n++) {
- if(arr[perm[n]] == endval) { /* if this is val (repeated) at end of last perm */
- if(allowed == 0) /* if repetition not allowed, force a new perm val */
- break;
- else /* else, repetitions still allowed */
- allowed--; /* decrement number of permissible further repets */
- } else {
- done = 1; /* if this is not val at end of last perm */
- break; /* perm is OK */
- }
- }
- }
- }
- /***************************** HHINSERT **********************************
- *
- * Insert the value m AFTER the T-th element in perm[].
- */
- void hhinsert(int m,int t,int setlen,int *perm)
- {
- hhshuflup(t+1,setlen,perm);
- perm[t+1] = m;
- }
- /***************************** HHPREFIX ************************************
- *
- * Insert the value m at start of the permutation perm[].
- */
- void hhprefix(int m,int setlen,int *perm)
- {
- hhshuflup(0,setlen,perm);
- perm[0] = m;
- }
- /****************************** HHSHUFLUP ***********************************
- *
- * move set members in perm[] upwards, starting from element k.
- */
- void hhshuflup(int k,int setlen,int *perm)
- {
- int n, *i;
- int z = setlen - 1;
- i = (perm+z);
- for(n = z;n > k;n--) {
- *i = *(i-1);
- i--;
- }
- }
- /****************************** ELIMINATE_SPURIOUS_MINIMA ***********************************/
- int eliminate_spurious_minima(int *local_minima_cnt,int *minimum_element_len,dataptr dz)
- {
- int exit_status;
- int *seg;
- int *segpos, badseg;
- int n, m, segcnt = (*local_minima_cnt) - 1, temp,eliminate_pos;
- double *peak = dz->parray[0];
- int *pos = dz->lparray[0];
- int maxseg, minseg, minsegstartpos;
- if((seg = (int *)malloc(segcnt * sizeof(int)))==NULL) {
- sprintf(errstr,"Insufficient memory (A) to check for spurious local minima\n");
- return(MEMORY_ERROR);
- }
- if((segpos = (int *)malloc(segcnt * sizeof(int)))==NULL) {
- sprintf(errstr,"Insufficient memory (B) to check for spurious local minima\n");
- return(MEMORY_ERROR);
- }
- for(;;) { /* RECURSIVELY ELIMINATE TOO-SHORT GAPS */
- for(n = 0; n < segcnt; n++)
- seg[n] = pos[n+1] - pos[n];
- for(n = 0; n < segcnt; n++)
- segpos[n] = n;
- for(n=0;n < segcnt-1; n++) { /* BUBBLE SORT THE GAPS BETWEEN LOCAL MINIMA TO DESCENDING SIZE ORDER */
- for(m=n+1;m < segcnt; m++) {
- if(seg[n] < seg[m]) {
- temp = seg[n];
- seg[n] = seg[m];
- seg[m] = temp;
- temp = segpos[n]; /* AND KEEP TRACK OF WHERE THESE NEWLY ORDERED GAPS ARE */
- segpos[n] = segpos[m];
- segpos[m] = temp;
- }
- }
- }
- maxseg = seg[0];
- minseg = seg[segcnt-1];
- badseg = 0; /* Compare minimum seg with maximum seg */
- if((double)minseg < (double)maxseg * dz->param[RRR_RANGE]) {
- badseg = 1;
- }
- if(!badseg) { /* No more anomalous segs found, exit loop */
- *minimum_element_len = minseg;
- break;
- }
- if(segcnt-1 < 3) {
- sprintf(errstr,"Insufficient valid local minima found during elimination of spurious minima. Are the search times incorrect??\n");
- return(DATA_ERROR);
- }
- minsegstartpos = segpos[segcnt-1]; /* Find positions of minimum seg start */
- if((exit_status = which_minimum_to_eliminate(minsegstartpos,pos,maxseg,segcnt,&eliminate_pos,dz)) < 0)
- return(exit_status);
- for(n=eliminate_pos ; n < (*local_minima_cnt)-1;n++) {
- peak[n] = peak[n+1]; /* Eliminate unwanted val, by moving values in array above it down 1 position */
- pos[n] = pos[n+1]; /* If BAD minimum is at current end of array, it just gets ignored as result of "local_minima_cnt--" */
- }
- (*local_minima_cnt)--; /* Reduce count of minima, and count of segs between minima */
- segcnt--;
- }
- return(FINISHED);
- }
- /****************************** FIND_ALL_POSITIVE_PEAKS ***********************************/
- int find_all_positive_peaks(int startsearch,int endsearch,int *peakcnt,dataptr dz)
- {
- double *peak = dz->parray[0], thispeak;
- int *pos = dz->lparray[0];
- float *ibuf = dz->sampbuf[0];
- int thissamp = startsearch, thispos;
- while(ibuf[thissamp] <= 0) { /* skip values below zero */
- if(++thissamp >= endsearch)
- break;
- }
- if(thissamp >= endsearch) {
- sprintf(errstr,"Cannot locate any peaks in the signal. Are the search times incorrect??\n");
- return(DATA_ERROR);
- }
- thispeak = ibuf[thissamp];
- thispos = thissamp;
- thissamp++;
- while(thissamp < endsearch) {
- if(ibuf[thissamp] >= 0.0) {
- if(ibuf[thissamp] > thispeak) { /* search for (positive) peak val */
- thispeak = ibuf[thissamp];
- thispos = thissamp;
- }
- } else {
- peak[*peakcnt] = thispeak; /* once signal becomes -ve3, store last found peak */
- pos[*peakcnt] = thispos;
- (*peakcnt)++;
- while(ibuf[thissamp] < 0) { /* then skip over -ve part of signal */
- if(++thissamp >= endsearch)
- break;
- }
- thispeak = ibuf[thissamp]; /* once dignal is +ve again, set up an initial value for peak */
- thispos = thissamp;
- }
- thissamp++;
- }
- if(*peakcnt > 0) { /* check for peak found near end, before signal goes -ve once more */
- if((thispos != pos[(*peakcnt)-1]) && (thispeak > 0.0)) {
- peak[*peakcnt] = thispeak;
- pos[*peakcnt] = thispos;
- (*peakcnt)++;
- }
- }
- if(*peakcnt < 3) {
- sprintf(errstr,"Insufficient signal peaks found. Are the search times incorrect??\n");
- return(DATA_ERROR);
- }
- return(FINISHED);
- }
- /****************************** FIND_ALL_LOCAL_MINIMA ***********************************/
- int find_all_local_minima(int peakcnt,int *local_minima_cnt,dataptr dz)
- {
- int thispeak;
- double *peak = dz->parray[0];
- int *pos = dz->lparray[0];
- /* double peakmin = peak[0];*/
- int finished = 0;
- *local_minima_cnt = 0;
- thispeak = 1;
- while(thispeak < peakcnt) {
- while(peak[thispeak] <= peak[thispeak-1]) { /* while peaks are falling, look for local peak minimum */
- if(++thispeak >= peakcnt) {
- finished = 1;
- break;
- }
- }
- if(finished)
- break;
- peak[*local_minima_cnt] = peak[thispeak-1]; /* store value and position of local mimimum */
- pos[*local_minima_cnt] = pos[thispeak-1];
- (*local_minima_cnt)++;
- while(peak[thispeak] >= peak[thispeak-1]) { /* skip over rising sequence of peaks */
- if(++thispeak >= peakcnt) {
- break;
- }
- }
- }
- if(*local_minima_cnt < 3) {
- sprintf(errstr,"Insufficient local minima found in inital search. Are the search times incorrect??\n");
- return(DATA_ERROR);
- }
- return(FINISHED);
- }
- /****************************** LOCATE_ZERO_CROSSINGS ***********************************/
- int locate_zero_crossings(int local_minima_cnt,dataptr dz)
- {
- int finished = 0;
- int n;
- float *ibuf = dz->sampbuf[0];
- double *peak = dz->parray[0];
- int *pos = dz->lparray[0];
- for(n=0;n<local_minima_cnt;n++) {
- while (peak[n] >= 0.0) { /* advance position from minimum +ve peak until value crosses zero */
- if(++pos[n] >= dz->insams[0]) {
- finished = 1;
- if(peak[n] > 0.0) { /* if end of file does not go to zero, Warn */
- fprintf(stdout,"WARNING: End_of_sound segment doesn't fall to zero level, & may cause clicks in output. (Dovetail end of sound?)\n");
- fflush(stdout);
- }
- break;
- }
- peak[n] = ibuf[pos[n]];
- }
- if(finished)
- break;
- }
- return(FINISHED);
- }
- /****************************** WHICH_MINIMUM_TO_ELIMINATE ***********************************
- *
- * Too short segment can be eliminated by deleting minimum at its start, or at its end.
- * Eliminating the minimum will make the preceding (or following) segment larger.
- * Deduce which of the two minima to delete.
- */
- int which_minimum_to_eliminate(int minsegstartpos,int *pos,int maxseg,int segcnt,int *eliminate_pos,dataptr dz)
- {
- int newpreseg, newpostseg, later_seg, prior_seg;
- double ratio, ratio2, presegratio=0, postsegratio=0;
- if(minsegstartpos == 0) { /* if minseg is at start of sequence */
- if(pos[2] - pos[0] > maxseg) /* losing end min of seg makes next seg bigger: if bigger than maxseg, eliminate start min instead */
- *eliminate_pos = minsegstartpos; /* effectively erasing the first seg */
- else /* else lose end min, making following seg larger */
- *eliminate_pos = minsegstartpos + 1;
- } else if(minsegstartpos + 1 == segcnt) { /* if minseg is at end of sequence */
- if(pos[minsegstartpos+1] - pos[minsegstartpos-1] > maxseg)
- *eliminate_pos = minsegstartpos + 1; /* if losing start min of seg makes prior seg > maxseg, eliminate end min instead */
- else /* else element start min, making previous seg larger */
- *eliminate_pos = minsegstartpos;
- /* ELSE we're not dealing with segs at ends of sequence */
- } else {
- newpreseg = (pos[minsegstartpos+1] - pos[minsegstartpos-1]); /* Find length new seg created by eliminating start min of shortest seg */
- newpostseg = (pos[minsegstartpos+2] - pos[minsegstartpos]); /* Find length new seg created by eliminating end min of shortest seg */
- if(newpreseg > maxseg || newpostseg > maxseg) { /* if either new seg is > maxseg */
- if(newpostseg <= maxseg) /* If ONLY preseg inter than maxseg, choose to make postseg, elim end min */
- *eliminate_pos = minsegstartpos + 1;
- else if(newpreseg <= maxseg) /* If ONLY postseg > maxseg, choose to make postseg, elim start min */
- *eliminate_pos = minsegstartpos;
- /* else if BOTH > maxseg, choose smaller */
- else if(newpreseg > newpostseg) /* if new preseg is larger, keep postseg, eliminate end min */
- *eliminate_pos = minsegstartpos + 1;
- else /* if new preseg is smaller, keep preseg, eliminate start min */
- *eliminate_pos = minsegstartpos;
- } else { /* both preseg and postseg are less than maxseg, choose seg that tallies best with local seg environment */
- if(segcnt <=3) { /* with only 3 segs, any deletion affects (increases sizeof) maxseg */
- /* Thus newly created seg, wherever it is, will be > sizeof orig maxseg, and will have been dealt with above */
- sprintf(errstr,"Programming error xxxx.\n");
- return(PROGRAM_ERROR);
- }
- /* find the maximum size ratio between new newpreseg and its adjacent segs */
- later_seg = pos[minsegstartpos+2] - pos[minsegstartpos+1];
- ratio = (double)newpreseg/(double)later_seg;
- if(ratio < 1.0)
- ratio = 1.0/ratio;
- if(minsegstartpos - 2 > 0) {
- prior_seg = pos[minsegstartpos-1] - pos[minsegstartpos-2];
- ratio2 = (double)newpreseg/(double)prior_seg;
- if(ratio2 < 1.0)
- ratio2 = 1.0/ratio2;
- ratio = max(ratio,ratio2);
- }
- presegratio = ratio;
- /* find the maximum size ratio between new newpostseg and its adjacent segs */
- ratio = 0.0;
- prior_seg = pos[minsegstartpos] - pos[minsegstartpos-1];
- ratio = (double)newpostseg/(double)prior_seg;
- if(ratio < 1.0)
- ratio = 1.0/ratio;
- if(minsegstartpos + 3 < segcnt) {
- later_seg = pos[minsegstartpos+3] - pos[minsegstartpos+2];
- ratio2 = (double)newpostseg/(double)later_seg;
- if(ratio2 < 1.0)
- ratio2 = 1.0/ratio2;
- ratio = max(ratio,ratio2);
- }
- postsegratio = ratio;
- }
- if(postsegratio < presegratio) /* if newpostseg makes better sense, eliminate end min */
- *eliminate_pos = minsegstartpos + 1;
- else /* else newporeseg makes better sense, elminate start min */
- *eliminate_pos = minsegstartpos;
- }
- return FINISHED;
- }
- /****************************** ELIMINATE_EXCESS_MINIMA ***********************************
- *
- * If no of segments found is >> anticipated segments, Group segments together in 'best' arrangement.
- */
- int eliminate_excess_minima(int *local_minima_cnt,int *pos,dataptr dz)
- {
- int n, m, j, bestgroup = 0; /* if found-segs is exact multiple of anticipated-segs, bestgrouping starts at position 0 */
- int more_than_possible = dz->insams[0]; /* i.e. too large to be reached by calculation */
- int segcnt = (*local_minima_cnt) - 1; /* Number of segs found e.g. 19 */
- 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 */
- /* if get=4 19/4 --> 4 by integer truncation */
- int remnant = (int)(segcnt - (grouping_cnt * dz->iparam[RRR_GET])); /* How many segments are then spare at start or end of sequence of segs */
- /* e.g. 19 - 16 = 3 */
- int diff, mindiff = more_than_possible;
- int grouped_len, max_grouped_len, min_grouped_len;
- 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 */
- grouped_len = 0; /* starting at 0,1,2,3 respectively */
- max_grouped_len = 0;
- min_grouped_len = more_than_possible;
- for(m=n;m < segcnt;m+=grouping_cnt) {
- for(j=0;j<grouping_cnt;j++) /* combine consecutive segs in groups of 'grouping_cnt', summing lengths */
- grouped_len += pos[m+j]; /* find max and min lengths of new grouped-segments */
- max_grouped_len = max(max_grouped_len,grouped_len);
- min_grouped_len = min(min_grouped_len,grouped_len);
- } /* Find range of the new lengths */
- diff = max_grouped_len - min_grouped_len;
- if(diff < mindiff)
- bestgroup = n; /* look for set of grouped-segments with lowest range */
- }
- for(n= 0,m=bestgroup;m < *local_minima_cnt;n++,m+=grouping_cnt)
- pos[n] = pos[m]; /* group orig segs by overwriting intermediate min-positions */
- *local_minima_cnt = n;
- return(FINISHED);
- }
- /************************* TIMESTRETCH_ITERATIVE2 *******************************/
- int timestretch_iterative2(dataptr dz)
- {
- int exit_status;
- /* double maxenv = 10000.0;*/
- int n, m, k, rrr_cnt, rrr_start=0, peakwidth;
- int *trofpnt;
- int trofpntcnt = 0, lasttrofpntcnt = 0;
- float lastenval;
- int could_be_rrr_flap, gotrrr = 0;
- int envcnt;
- fprintf(stdout,"INFO: Searching file envelope.\n");
- fflush(stdout);
- rrr_cnt = -dz->iparam[RRR_SKIP]; /* Number of iterate units to skip before utilising any of them */
- if(((envcnt = dz->insams[0]/dz->iparam[RRR_SAMP_WSIZENU]) * dz->iparam[RRR_SAMP_WSIZENU])!=dz->insams[0])
- envcnt++;
- if((dz->env=(float *)malloc((envcnt+20) * sizeof(float)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for envelope array.\n");
- return(MEMORY_ERROR);
- }
- if((exit_status = extract_rrr_env_from_sndfile(RRR_SAMP_WSIZENU,dz))<0)
- return(exit_status);
- if((trofpnt = (int *)malloc(envcnt * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY TO ANALYSE ENVELOPE.\n");
- return(MEMORY_ERROR);
- }
- trofpnt[0] = 0;
- lastenval = dz->env[0];
- n = 1;
- while(n < envcnt) { /* GET FIRST ENVELOPE TROUGH */
- if(dz->env[n] > lastenval) {
- trofpnt[0] = 0;
- lastenval = dz->env[n];
- n++;
- break;
- } else if (dz->env[n] < lastenval) {
- trofpnt[0] = n;
- lastenval = dz->env[n];
- n++;
- break;
- }
- lastenval = dz->env[n];
- n++;
- }
- if(n >= envcnt) {
- sprintf(errstr,"NO PEAKS FOUND IN ENVELOPE\n");
- return(GOAL_FAILED);
- }
- while(n < envcnt) { /* GET ENVELOPE TROUGHS */
- if(dz->env[n] > lastenval) {
- trofpntcnt = lasttrofpntcnt + 1;
- } else if (dz->env[n] < lastenval) {
- trofpnt[trofpntcnt] = n;
- lasttrofpntcnt = trofpntcnt;
- }
- lastenval = dz->env[n];
- n++;
- }
- if(trofpntcnt < 2) {
- sprintf(errstr,"NO SIGNIFICANT PEAKS FOUND IN ENVELOPE\n");
- return(GOAL_FAILED);
- }
- for(m = 0, n=1;n<trofpntcnt;m++,n++) {
- peakwidth = trofpnt[n] - trofpnt[m];
- if(peakwidth > 2 && peakwidth < 6) { /* IF PEAK WIDTH IS WITHIN LIMITS FOR AN ITERATE-UNIT */
- could_be_rrr_flap = 0;
- for(k = trofpnt[m]; k < trofpnt[n]; k++) { /* AND PEAK IS ABOVE GATE */
- if(dz->env[k] > dz->param[RRR_GATE]) {
- could_be_rrr_flap = 1;
- break;
- }
- }
- if(could_be_rrr_flap) {
- if(rrr_cnt == 0) /* IF (skipped unwanted flaps &) NO FLAPS HERE YET */
- rrr_start = m; /* MARK START OF A POSSIBLE FLAP */
- rrr_cnt++; /* COUNT FLAPS */
- }
- } else {
- could_be_rrr_flap = 0; /* MARK NON-FLAP */
- }
- if (!could_be_rrr_flap) {
- if(rrr_cnt >= dz->iparam[RRR_GET]) { /* IF END OF FLAPS, AND WE HAVE ENOUGH ADJACENT FLAPS */
- /* SET PARAMS FOR ZER-CROSSING SEARCH */
- dz->iparam[RRR_START] = trofpnt[rrr_start] * dz->iparam[RRR_SAMP_WSIZENU];
- dz->iparam[RRR_START] -= dz->iparam[RRR_SAMP_WSIZENU]/ 2; /* Start search before first flap segment */
- dz->iparam[RRR_START] = max(0,dz->iparam[RRR_START]);
- dz->iparam[RRR_END] = trofpnt[m] * dz->iparam[RRR_SAMP_WSIZENU];;
- dz->iparam[RRR_END] += dz->iparam[RRR_SAMP_WSIZENU]/ 2; /* End search after last flap segment */
- dz->iparam[RRR_END] = min(dz->insams[0],dz->iparam[RRR_END]);
- dz->param[RRR_START] = (double)dz->iparam[RRR_START]/dz->infile->srate;
- dz->param[RRR_END] = (double)dz->iparam[RRR_END]/dz->infile->srate;
- // dz->iparam[RRR_GET] = rrr_cnt;
- // EXPERIMENTAL!! FORCES zero-cross algo to get better result
- // 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
- // However, if algo finds 7 zcs and there are really rrr_cnt=4
- // 7 < (2*4), so it doesn't group the zcs in twos, so 7 zcs are kept, probalby too many...
- // 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
- dz->iparam[RRR_GET] = rrr_cnt - 1;
- gotrrr = 1;
- break;
- } else {
- rrr_cnt = -dz->iparam[RRR_SKIP];
- }
- }
- }
- if(gotrrr == 0) {
- sprintf(errstr,"NO ITERATIVE LOCATION FOUND\n");
- return(GOAL_FAILED);
- } else {
- fprintf(stdout,"INFO: searching between %.04lf and %.04lf secs: where %d peaks found\n",dz->param[RRR_START],dz->param[RRR_END],rrr_cnt);
- fflush(stdout);
- }
- return timestretch_iterative(dz);
- }
- /************************* EXTRACT_RRR_ENV_FROM_SNDFILE *******************************/
- int extract_rrr_env_from_sndfile(int paramno,dataptr dz)
- {
- int n;
- float *envptr;
- int bufcnt;
- if(((bufcnt = dz->insams[0]/dz->buflen)*dz->buflen)!=dz->insams[0])
- bufcnt++;
- envptr = dz->env;
- for(n = 0; n < bufcnt; n++) {
- if((dz->ssampsread = fgetfbufEx(dz->sampbuf[0], dz->buflen,dz->ifd[0],0)) < 0) {
- sprintf(errstr,"Can't read samples from soundfile: extract_rrr_env_from_sndfile()\n");
- return(SYSTEM_ERROR);
- }
- if(sloom)
- display_virtual_time(dz->total_samps_read,dz);
- get_rrrenv_of_buffer(dz->ssampsread,dz->iparam[paramno],&envptr,dz->sampbuf[0]);
- }
- dz->envend = envptr;
- return(FINISHED);
- }
- /************************* GET_RRRENV_OF_BUFFER *******************************/
- void get_rrrenv_of_buffer(int samps_to_process,int envwindow_sampsize,float **envptr,float *buffer)
- {
- int start_samp = 0;
- float *env = *envptr;
- while(samps_to_process >= envwindow_sampsize) {
- *env++ = getmaxsampr(start_samp,envwindow_sampsize,buffer);
- start_samp += envwindow_sampsize;
- samps_to_process -= envwindow_sampsize;
- }
- if(samps_to_process) /* Handle any final short buffer */
- *env++ = getmaxsampr(start_samp,samps_to_process,buffer);
- *envptr = env;
- }
- /*************************** GETMAXSAMPR ******************************/
- float getmaxsampr(int startsamp, int sampcnt,float *buffer)
- {
- int i, endsamp = startsamp + sampcnt;
- float thisval, thismaxsamp = 0.0f;
- for(i = startsamp; i<endsamp; i++) {
- if((thisval = (float)fabs(buffer[i]))>thismaxsamp)
- thismaxsamp = thisval;
- }
- return(thismaxsamp);
- }
- /********************************** GRAB_NOISE_AND_EXPAND **********************************
- *
- * Locate noise, then expand it by random-reads from zero-cross to zero-cross
- */
- int grab_noise_and_expand(dataptr dz)
- {
- int exit_status;
- float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1];
- int phase, initialphase, isnoise = -1, finished = 0;
- int j, k, n, m, waveset_cnt;
- int lastzcross = 0, sampstart, sampend, len, temp, orig_buflen;
- int brkpntcnt = 0, got_noise = 0;
- double maxsamp, gate = dz->param[SSS_GATE];
- int abovegate = 0;
- if((dz->lparray[0] = (int *)malloc(dz->insams[0] * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY.\n");
- return(DATA_ERROR);
- }
- fprintf(stdout,"INFO: Searching for noise.\n");
- fflush(stdout);
- orig_buflen = dz->buflen;
- dz->buflen = dz->insams[0];
- if((exit_status = read_samps(ibuf,dz))<0)
- return(exit_status);
- else if(dz->ssampsread <= 0) {
- sprintf(errstr,"Failed to read sound from input file\n");
- return(DATA_ERROR);
- }
- dz->buflen = orig_buflen;
- /* ESTABLISH INITIAL PHASE OF SIGNAL */
- n = 0;
- while(ibuf[n]==0) {
- if(++n >= dz->ssampsread) {
- sprintf(errstr,"FAILED TO FIND ANY WAVECYCLES IN FILE.\n");
- return(DATA_ERROR);
- }
- }
- if(ibuf[n] > 0)
- initialphase = 1;
- else
- initialphase = -1;
- for(;;) {
- /* FIND A WAVECYCLE */
- maxsamp = 0.0;
- if(initialphase == 1) {
- while(ibuf[n] > 0) {
- maxsamp = max(maxsamp,ibuf[n]);
- if(++n >= dz->ssampsread) {
- finished = 1;
- break;
- }
- }
- while(ibuf[n] <= 0) {
- maxsamp = max(maxsamp,-ibuf[n]);
- if(++n >= dz->ssampsread) {
- finished = 1;
- break;
- }
- }
- } else {
- while(ibuf[n] < 0) {
- maxsamp = max(maxsamp,-ibuf[n]);
- if(++n >= dz->ssampsread) {
- finished = 1;
- break;
- }
- }
- while(ibuf[n] >= 0) {
- maxsamp = max(maxsamp,ibuf[n]);
- if(++n >= dz->ssampsread) {
- finished = 1;
- break;
- }
- }
- }
- if(finished)
- break;
- if(maxsamp < gate)
- isnoise = 0;
- else {
- abovegate = 1;
- dz->lparray[0][brkpntcnt] = n;
- /* MEASURE WAVE-CYCLE LENGTH, AND TEST FOR NOISE */
- /* IF SIGNAL SWITCHES FROM NOISE to NOT-NOISE or vice versa, STORE THAT POSITION */
- if(dz->lparray[0][brkpntcnt] - lastzcross < dz->iparam[NOISE_MINFRQ]) {
- if(brkpntcnt == 0) /* if noise-start pos, move to search for noise-end position */
- brkpntcnt = 1;
- else if(dz->lparray[0][1] - dz->lparray[0][0] >= dz->iparam[MAX_NOISLEN]) {
- got_noise = 1;
- break;
- }
- isnoise = 1;
- } else {
- if(isnoise == 1) { /* if at end of noise ... */
- /* if enough noise present ... break */
- if(dz->lparray[0][1] - dz->lparray[0][0] > dz->iparam[MIN_NOISLEN]) {
- got_noise = 1;
- break;
- } else { /* if NOT ENOUGH noise present, delete noise pos data, start again */
- dz->lparray[0][0] = dz->lparray[0][1];
- brkpntcnt = 0;
- }
- }
- isnoise = 0;
- }
- }
- lastzcross = n; /* store position of last waveset end... */
- }
- /* CHECK THAT ANY NOISE : non-NOISE SWITCHES FOUND */
- if(!abovegate) {
- sprintf(errstr,"NO SIGNAL IS ABOVE THE GATE LEVEL\n");
- return(GOAL_FAILED);
- }
- if(!got_noise) {
- if(gate > 0)
- sprintf(errstr,"NO NOISE FOUND WITH GATE-LEVEL %lf\n",gate);
- else
- sprintf(errstr,"NO NOISE FOUND\n");
- return(GOAL_FAILED);
- }
- fprintf(stdout,"INFO: Generating output.\n");
- fflush(stdout);
- sampstart = dz->lparray[0][0];
- sampend = dz->lparray[0][1];
- waveset_cnt = 0;
- if(ibuf[sampstart] > 0) {
- initialphase = 1;
- phase = 1;
- dz->lparray[0][waveset_cnt++] = sampstart;
- } else if (ibuf[sampstart] < 0) {
- initialphase = -1;
- phase = -1;
- dz->lparray[0][waveset_cnt++] = sampstart;
- } else
- phase = 0;
- /* STORE ZERO-CROSS-PAIR POSITIONS */
- for(n = sampstart+1;n < sampend; n++) {
- switch(phase) {
- case(0):
- if(ibuf[n] > 0) {
- phase = 1;
- initialphase = 1;
- dz->lparray[0][waveset_cnt++] = n;
- } else if(ibuf[n] < 0) {
- phase = -1;
- initialphase = -1;
- dz->lparray[0][waveset_cnt++] = n;
- }
- break;
- case(1):
- if(ibuf[n] < 0) {
- if(initialphase == -1)
- dz->lparray[0][waveset_cnt++] = n;
- phase = -1;
- }
- break;
- case(-1):
- if(ibuf[n] > 0) {
- if(initialphase == 1)
- dz->lparray[0][waveset_cnt++] = n;
- phase = 1;
- }
- break;
- }
- }
- j = 0;
- if(!dz->vflag[0]) {
- for(n=0;n<sampstart;n++) {
- obuf[j++] = ibuf[n];
- if(j >= dz->buflen) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- j = 0;
- }
- }
- }
- for(;;) {
- n = (int)floor(drand48() * waveset_cnt); /* RANDOM READS TO AND FROM ZERO-CROSSINGS */
- do {
- m = (int)floor(drand48() * waveset_cnt);
- } while (m == n);
- if((len = dz->lparray[0][m] - dz->lparray[0][n]) < 0) {
- temp = m;
- m = n;
- n = temp;
- len = -len;
- }
- if(j + len >= dz->iparam[SSS_DUR]) /* HALT AT A ZERO CROSSING */
- break;
- for(k= dz->lparray[0][n]; k < dz->lparray[0][m];k++) {
- obuf[j++] = ibuf[k];
- if(j >= dz->buflen) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- dz->iparam[SSS_DUR] -= dz->buflen;
- j = 0;
- }
- }
- }
- if(!dz->vflag[0]) {
- for(n=sampend;n<dz->insams[0];n++) {
- obuf[j++] = ibuf[n];
- if(j >= dz->buflen) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- j = 0;
- }
- }
- }
- if(j > 0) {
- if((exit_status = write_samps(obuf,j,dz))<0)
- return(exit_status);
- }
- return(FINISHED);
- }
- /************************** GREV **********************/
- int grev(dataptr dz)
- {
- int exit_status, finished, start_negative;
- int n, j=0, k, minpeakloc, envcnt, last_total_samps_read, startsearch, endsearch, obufpos;
- int lastobufpos, step, expansion, lastgrainlen=0, nu_gp_dur;
- double maxsamp0, maxsamp1, peakav, minpeakav, time;
- int firsttrof, up, gotmaxsamp0, crossed_zero_to_positive, crossed_zero_to_negative, gp=0, read_brk = 0;
- float *e, *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1];
- int *pa;
- double convertor = 1.0 / dz->infile->srate;
- if(((envcnt = dz->insams[0]/dz->iparam[GREV_SAMP_WSIZE]) * dz->iparam[GREV_SAMP_WSIZE])!=dz->insams[0])
- envcnt++;
- if((dz->env=(float *)malloc((envcnt + 12) * sizeof(float)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for envelope array.\n");
- return(MEMORY_ERROR);
- }
- e = dz->env;
- if((pa =(int *)malloc((envcnt + 12) * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for peak positions array.\n");
- return(MEMORY_ERROR);
- }
- if((exit_status = extract_rrr_env_from_sndfile(GREV_SAMP_WSIZE,dz))<0) /* Get envel of whole sound */
- return(exit_status);
- dz->total_samps_read = 0;
- display_virtual_time(0,dz);
- envcnt = dz->envend - dz->env;
- n = 0;
- k = 0;
- pa[k++] = 0;
- while(flteq(e[n],e[0])) {
- n++;
- if(n >= envcnt) {
- sprintf(errstr,"NO PEAKS IN THE FILE\n");
- return(GOAL_FAILED);
- }
- }
- if(e[n] < e[0]) {
- firsttrof = 1;
- up = -1;
- } else {
- firsttrof = 0;
- up = 1;
- }
- /* KEEP ONLY THE PEAKS AND TROUGHS OF THE ENVELOPE, AND THEIR LOCATIONS */
- while (n <envcnt) { /* store peaks and troughs only */
- switch(up) {
- case(1):
- if(e[n] < e[n-1]) {
- dz->env[k] = dz->env[n-1];
- pa[k] = (n-1) * dz->iparam[GREV_SAMP_WSIZE];
- k++;
- up = -1;
- }
- break;
- case(-1):
- if(e[n] > e[n-1]) {
- dz->env[k] = dz->env[n-1];
- pa[k] = (n-1) * dz->iparam[GREV_SAMP_WSIZE];
- k++;
- up = 1;
- }
- break;
- }
- n++;
- }
- if((envcnt = k) <= 3) {
- sprintf(errstr,"INSUFFICIENT PEAKS IN THE FILE.\n");
- return(GOAL_FAILED);
- }
- /* KEEP ONLY THE (DEEP ENOUGH) TROUGHS OF THE ENVELOPE */
- switch(firsttrof) {
- case(0): /* if trof at start */
- k = 1; /* set item at 0 NOT to be overwritten (as it is first trof) (set k=1) */
- j = 1; /* search for good trofs between peaks, from (j=)1 */
- break;
- case(1): /* if trof not at start */
- k = 0; /* set item at 0 to be overwritten by 1st trof found (k=0) */
- j = 0; /* search for good trofs between peaks, from (j=)0 */
- break;
- }
- for(n=j;n<envcnt-2;n++) {
- peakav = dz->env[n] + dz->env[n+2];
- if(peakav * dz->param[GREV_TROFRAC] >= dz->env[n+1]) { /* NB TROF_FAC alreday PRE-MULTIPLIED by 2.0 */
- pa[k] = pa[n+1];
- k++;
- }
- }
- if((envcnt = k) <= 3) {
- sprintf(errstr,"INSUFFICIENT VALID TROUGHS IN THE FILE.\n");
- return(GOAL_FAILED);
- }
- /* SEARCH WAVEFORM FOR ZERO_CROSSING AT MORE ACCURATE TROUGH */
- fprintf(stdout,"INFO: Number of grains found = %d\n",envcnt);
- fflush(stdout);
- if((sndseekEx(dz->ifd[0],0,0))<0) {
- sprintf(errstr,"seek error 1\n");
- return(SYSTEM_ERROR);
- }
- last_total_samps_read = 0;
- k = (int)round((double)dz->iparam[GREV_SAMP_WSIZE] * 0.5); /* search around size of envel window */
- startsearch = max(pa[0] - k, 0);
- endsearch = min(pa[0] + k,dz->insams[0]);
- dz->total_samps_read = 0;
- while(startsearch > dz->buflen) {
- dz->total_samps_read += dz->buflen;
- startsearch -= dz->buflen;
- }
- if(dz->total_samps_read > 0) {
- if((sndseekEx(dz->ifd[0],dz->total_samps_read,0))<0) {
- sprintf(errstr,"seek error 2\n");
- return(SYSTEM_ERROR);
- }
- last_total_samps_read = dz->total_samps_read;
- endsearch -= last_total_samps_read;
- }
- if((exit_status = read_samps(ibuf,dz))<0)
- return(exit_status);
- n = 0;
- finished = 0;
- while(n<envcnt) {
- maxsamp0 = 0.0;
- maxsamp1 = 0.0;
- gotmaxsamp0 = 0;
- minpeakav = HUGE;
- minpeakloc = -1;
- j = startsearch;
- crossed_zero_to_positive = 0;
- crossed_zero_to_negative = 0;
- if(ibuf[j] <= 0)
- start_negative = 1;
- else
- start_negative = 0;
- do {
- if(j >= dz->ssampsread) {
- last_total_samps_read = dz->total_samps_read;
- endsearch -= dz->buflen;
- j -= dz->buflen;
- if((exit_status = read_samps(ibuf,dz))<0)
- return(exit_status);
- if(dz->ssampsread == 0) {
- finished = 1;
- break;
- }
- }
- if(!crossed_zero_to_negative) { /* before signal crosses to negative */
- if(start_negative) {
- if(ibuf[j] <= 0.0) {
- j++;
- continue;
- }
- start_negative = 0;
- }
- if(!gotmaxsamp0) { /* First time only, look for first maxsamp */
- if(ibuf[j] > maxsamp0) /* (after first time, it gets val passed back from 2nd maxsamp */
- maxsamp0 = ibuf[j];
- }
- if (ibuf[j] < 0.0) { /* if not crossed zero to -ve, look for, and mark, zero-cross to -ve */
- crossed_zero_to_negative = j + last_total_samps_read;
- gotmaxsamp0 = 1;
- }
- } else if (ibuf[j] >= 0) { /* if crossed zero to neg and we're now crossing back to +ve */
- crossed_zero_to_positive = 1;
- if(ibuf[j] > maxsamp1) /* look for 2nd maxsamp */
- maxsamp1 = ibuf[j];
- } else if (crossed_zero_to_positive) { /* having crossed from -ve to +ve, we're now -ve again, in a new cycle */
- if((peakav = maxsamp0 + maxsamp1) < minpeakav) {
- minpeakav = peakav;
- minpeakloc = crossed_zero_to_negative;
- }
- maxsamp0 = maxsamp1;
- crossed_zero_to_positive = 0;
- crossed_zero_to_negative = 0;
- }
- j++;
- } while(j < endsearch || minpeakloc < 0);
- if(minpeakloc < 0) {
- if (finished) { /* deal with endcases where waveform fails to cross zero (twice) */
- if(crossed_zero_to_negative > 0)
- pa[n++] = crossed_zero_to_negative;
- envcnt = n;
- break;
- } else {
- sprintf(errstr,"FAILED TO FIND ONE OF THE LOCAL MINIMA.\n");
- return(PROGRAM_ERROR);
- }
- }
- pa[n] = minpeakloc;
- n++;
- startsearch = max(pa[n] - k, 0);
- endsearch = min(pa[n] + k,dz->insams[0]);
- if(startsearch >= dz->total_samps_read) {
- while(startsearch >= dz->total_samps_read) {
- last_total_samps_read = dz->total_samps_read;
- if((exit_status = read_samps(ibuf,dz))<0)
- return(exit_status);
- if(last_total_samps_read >= dz->total_samps_read) {
- envcnt = n;
- break;
- }
- }
- }
- startsearch -= last_total_samps_read;
- endsearch -= last_total_samps_read;
- while(startsearch < 0) { /* very tiny windows may cause backtracking in file */
- last_total_samps_read -= dz->buflen;
- if((sndseekEx(dz->ifd[0],last_total_samps_read,0))<0) {
- sprintf(errstr,"seek error 3\n");
- return(SYSTEM_ERROR);
- }
- if((exit_status = read_samps(ibuf,dz))<0)
- return(exit_status);
- dz->total_samps_read = last_total_samps_read + dz->ssampsread;
- startsearch += dz->buflen;
- endsearch += dz->buflen;
- }
- }
- if((sndseekEx(dz->ifd[0],0,0))<0) {
- sprintf(errstr,"seek error 4\n");
- return(SYSTEM_ERROR);
- }
- dz->total_samps_read = 0;
- last_total_samps_read = 1; /* Value 1 forces first seek and read */
- obufpos = 0;
- switch(dz->mode) {
- case(GREV_REVERSE):
- if(!dz->brksize[GREV_GPCNT])
- gp = dz->iparam[GREV_GPCNT];
- for(n = envcnt - (2 * gp); n>0; n-=gp) {
- startsearch = pa[n];
- if(dz->brksize[GREV_GPCNT]) {
- time = (double)startsearch * convertor;
- if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
- return(exit_status);
- gp = (int)round(dz->param[GREV_GPCNT]);
- }
- endsearch = pa[n + gp];
- if((exit_status = do_envgrain_write(startsearch,endsearch,&last_total_samps_read,&obufpos,dz))<0)
- return(exit_status);
- }
- break;
- case(GREV_REPEAT):
- if(!dz->brksize[GREV_GPCNT])
- gp = dz->iparam[GREV_GPCNT];
- if(dz->brksize[GREV_REPETS] || dz->brksize[GREV_GPCNT])
- read_brk = 1;
- for(n = 0; n<=(envcnt-gp); n+=gp) {
- startsearch = pa[n];
- if(read_brk) {
- time = (double)startsearch * convertor;
- if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
- return(exit_status);
- }
- if(dz->brksize[GREV_GPCNT])
- gp = (int)round(dz->param[GREV_GPCNT]);
- if(dz->brksize[GREV_REPETS])
- dz->iparam[GREV_REPETS] = (int)round(dz->param[GREV_REPETS]);
- endsearch = pa[n + gp];
- for(k = 0;k < dz->iparam[GREV_REPETS];k++) {
- if((exit_status = do_envgrain_write(startsearch,endsearch,&last_total_samps_read,&obufpos,dz))<0)
- return(exit_status);
- }
- }
- break;
- case(GREV_DELETE):
- if(!dz->brksize[GREV_GPCNT])
- gp = dz->iparam[GREV_GPCNT];
- if(dz->brksize[GREV_KEEP] || dz->brksize[GREV_GPCNT])
- read_brk = 1;
- for(n = 0; n<=(envcnt-gp); n+=gp) {
- startsearch = pa[n];
- if(read_brk) {
- time = (double)startsearch * convertor;
- if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
- return(exit_status);
- }
- if(dz->brksize[GREV_GPCNT])
- gp = (int)round(dz->param[GREV_GPCNT]);
- if(dz->brksize[GREV_KEEP])
- dz->iparam[GREV_KEEP] = (int)round(dz->param[GREV_KEEP]);
- endsearch = pa[n + gp];
- if((n % dz->iparam[GREV_OUTOF]) < dz->iparam[GREV_KEEP]) {
- if((exit_status = do_envgrain_write(startsearch,endsearch,&last_total_samps_read,&obufpos,dz))<0)
- return(exit_status);
- }
- }
- break;
- case(GREV_OMIT):
- if(!dz->brksize[GREV_GPCNT])
- gp = dz->iparam[GREV_GPCNT];
- if(dz->brksize[GREV_KEEP] || dz->brksize[GREV_GPCNT])
- read_brk = 1;
- for(n = 0; n<=(envcnt-gp); n+=gp) {
- startsearch = pa[n];
- if(read_brk) {
- time = (double)startsearch * convertor;
- if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
- return(exit_status);
- }
- if(dz->brksize[GREV_GPCNT])
- gp = (int)round(dz->param[GREV_GPCNT]);
- if(dz->brksize[GREV_KEEP])
- dz->iparam[GREV_KEEP] = (int)round(dz->param[GREV_KEEP]);
- endsearch = pa[n + gp];
- if((n % dz->iparam[GREV_OUTOF]) < dz->iparam[GREV_KEEP]) {
- if((exit_status = do_envgrain_write(startsearch,endsearch,&last_total_samps_read,&obufpos,dz))<0)
- return(exit_status);
- } else {
- if((exit_status = do_envgrain_zerowrite(startsearch,endsearch,&obufpos,dz))<0)
- return(exit_status);
- }
- }
- break;
- case(GREV_TSTRETCH):
- if(!dz->brksize[GREV_GPCNT])
- gp = dz->iparam[GREV_GPCNT];
- if(dz->brksize[GREV_TSTR] || dz->brksize[GREV_GPCNT])
- read_brk = 1;
- for(n = 0; n<=envcnt-1; n++) {
- startsearch = pa[n];
- if(read_brk) {
- time = (double)startsearch * convertor;
- if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
- return(exit_status);
- }
- if(dz->brksize[GREV_GPCNT])
- gp = (int)round(dz->param[GREV_GPCNT]);
- endsearch = pa[n + 1];
- lastobufpos = obufpos + dz->total_samps_written;
- if((exit_status = do_envgrain_addwrite(startsearch,endsearch,&last_total_samps_read,&obufpos,dz))<0)
- return(exit_status);
- step = obufpos + dz->total_samps_written - lastobufpos;
- expansion = (int)round((double)step * dz->param[GREV_TSTR]) - step;
- if(expansion > 0) {
- if((exit_status = do_envgrain_zerowrite_dblbuf(0,expansion,&obufpos,dz))<0)
- return(exit_status);
- } else
- obufpos += expansion;
- }
- break;
- case(GREV_GET):
- if(!dz->brksize[GREV_GPCNT])
- gp = dz->iparam[GREV_GPCNT];
- else
- read_brk = 1;
-
- for(n = 0; n<=(envcnt-gp); n+=gp) {
- startsearch = pa[n];
- if(read_brk) {
- time = (double)startsearch * convertor;
- if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
- return(exit_status);
- }
- if(dz->brksize[GREV_GPCNT])
- gp = (int)round(dz->param[GREV_GPCNT]);
- fprintf(dz->fp,"%d\n",startsearch);
- }
- break;
- case(GREV_PUT):
- if(!dz->brksize[GREV_GPCNT])
- gp = dz->iparam[GREV_GPCNT];
- else
- read_brk = 1;
- for(n = 0; n<=(envcnt-gp); n+=gp) {
- startsearch = pa[n];
- if(read_brk) {
- time = (double)startsearch * convertor;
- if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
- return(exit_status);
- }
- if(dz->brksize[GREV_GPCNT])
- gp = (int)round(dz->param[GREV_GPCNT]);
- endsearch = pa[n + gp];
- if(n > 0) {
- if(n >= dz->itemcnt)
- break;
- nu_gp_dur = (int)round(dz->parray[GR_SYNCTIME][n] - dz->parray[GR_SYNCTIME][n-1]);
- obufpos += (nu_gp_dur - lastgrainlen);
- if(obufpos <= -dz->buflen) {
- sprintf(errstr,"BACKTRACK TOO LARGE\n");
- return(GOAL_FAILED);
- }
- }
- if((exit_status = do_envgrain_write(startsearch,endsearch,&last_total_samps_read,&obufpos,dz))<0)
- return(exit_status);
- lastgrainlen = endsearch - startsearch;
- }
- break;
- }
- if(obufpos > 0) {
- if((exit_status = write_samps(obuf,obufpos,dz))<0)
- return(exit_status);
- }
- return(FINISHED);
- }
- /************************** DO_ENVGRAIN_WRITE **********************/
- int do_envgrain_write(int startsearch,int endsearch,int *last_total_samps_read,int *obufpos,dataptr dz)
- {
- int exit_status;
- int step, n, m, limit = dz->buflen;
- float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1];
- if(startsearch > dz->total_samps_read || startsearch < *last_total_samps_read) {
- step = (startsearch / dz->buflen) * dz->buflen;
- if((sndseekEx(dz->ifd[0],step,0))<0) {
- sprintf(errstr,"seek error 5\n");
- return(SYSTEM_ERROR);
- }
- *last_total_samps_read = step;
- if((exit_status = read_samps(ibuf,dz))<0)
- return(exit_status);
- dz->total_samps_read = *last_total_samps_read + dz->ssampsread;
- }
- startsearch -= *last_total_samps_read;
- endsearch -= *last_total_samps_read;
- m = *obufpos;
- if(dz->mode == GREV_PUT) {
- limit *= 2;
- while(m >= limit) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- memcpy((char *)dz->sampbuf[1],(char *)dz->sampbuf[2],dz->buflen * sizeof(float));
- memset((char *)dz->sampbuf[2],0,dz->buflen * sizeof(float));
- m -= dz->buflen;
- }
- }
- for(n=startsearch;n <endsearch;n++) {
- if(n >= dz->buflen) {
- *last_total_samps_read = dz->total_samps_read;
- if((exit_status = read_samps(ibuf,dz))<0)
- return(exit_status);
- n = 0;
- endsearch -= dz->buflen;
- }
- obuf[m++] = ibuf[n];
- if(m >= limit) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- if(dz->mode == GREV_PUT) { /* deals with bufptr < 0 */
- memcpy((char *)dz->sampbuf[1],(char *)dz->sampbuf[2],dz->buflen * sizeof(float));
- memset((char *)dz->sampbuf[2],0,dz->buflen * sizeof(float));
- m = dz->buflen;
- } else
- m = 0;
- }
- }
- *obufpos = m;
- return(FINISHED);
- }
- /************************** DO_ENVGRAIN_ZEROWRITE **********************/
- int do_envgrain_zerowrite(int startsearch,int endsearch,int *obufpos,dataptr dz)
- {
- int exit_status;
- int n, m;
- float *obuf = dz->sampbuf[1];
- m = *obufpos;
- for(n=startsearch;n <endsearch;n++) {
- if(m >= dz->buflen) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- m = 0;
- }
- obuf[m++] = 0.0;
- }
- *obufpos = m;
- return(FINISHED);
- }
- /************************** DO_ENVGRAIN_ZEROWRITE_DBLBUF **********************/
- int do_envgrain_zerowrite_dblbuf(int startsearch,int endsearch,int *obufpos,dataptr dz)
- {
- int exit_status;
- int n, m;
- float *obuf = dz->sampbuf[1], *obuf2 = dz->sampbuf[2];
- m = *obufpos;
- for(n=startsearch;n <endsearch;n++) {
- if(m >= dz->buflen * 2) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- memcpy((char *)obuf,(char *)obuf2,dz->buflen * sizeof(float));
- memset((char *)obuf2,0,dz->buflen * sizeof(float));
- m -= dz->buflen;
- }
- obuf[m++] = 0.0;
- }
- *obufpos = m;
- return(FINISHED);
- }
- /************************** DO_ENVGRAIN_ADDWRITE **********************/
- int do_envgrain_addwrite(int startsearch,int endsearch,int *last_total_samps_read,int *obufpos,dataptr dz)
- {
- int exit_status;
- int step, n, m;
- float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1], *obuf2 = dz->sampbuf[2];
- if(*obufpos < 0) {
- sprintf(errstr,"GRAIN TOO LARGE TO BACKTRACK IN BUFFER.\n");
- return(GOAL_FAILED);
- }
- if(startsearch > dz->total_samps_read || startsearch < *last_total_samps_read) {
- step = (startsearch / dz->buflen) * dz->buflen;
- if((sndseekEx(dz->ifd[0],step,0))<0) {
- sprintf(errstr,"seek error 6\n");
- return(SYSTEM_ERROR);
- }
- *last_total_samps_read = step;
- if((exit_status = read_samps(ibuf,dz))<0)
- return(exit_status);
- dz->total_samps_read = *last_total_samps_read + dz->ssampsread;
- }
- startsearch -= *last_total_samps_read;
- endsearch -= *last_total_samps_read;
- m = *obufpos;
- for(n=startsearch;n <endsearch;n++) {
- if(n >= dz->buflen) {
- *last_total_samps_read = dz->total_samps_read;
- if((exit_status = read_samps(ibuf,dz))<0)
- return(exit_status);
- n = 0;
- endsearch -= dz->buflen;
- }
- obuf[m++] += ibuf[n];
- if(m >= dz->buflen * 2) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- memcpy((char *)obuf,(char *)obuf2,dz->buflen * sizeof(float));
- memset((char *)obuf2,0,dz->buflen * sizeof(float));
- m -= dz->buflen;
- }
- }
- *obufpos = m;
- return(FINISHED);
- }
- /****************************** TIMESTRETCH_ITERATIVE ****************************/
- int timestretch_iterative3(dataptr dz)
- {
- int exit_status;
- float *obuf = dz->sampbuf[0];
- int *pos = dz->lparray[0];
- int peakcnt, startsearch, endsearch, local_minima_cnt, minimum_element_len;
- int n,z = 0, outpos, samps_to_write;
- char *outfilename;
-
- int namelen = strlen(dz->wordstor[0]);
- if((outfilename = (char *)malloc(namelen + 4))==NULL) {
- sprintf(errstr,"Insufficient memory\n");
- return(MEMORY_ERROR);
- }
- strcpy(outfilename,dz->wordstor[0]);
- fprintf(stdout,"INFO: Generating output.\n");
- fflush(stdout);
- if(sloom)
- display_virtual_time(0,dz);
- if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
- return(exit_status);
- dz->sampbuf[0][dz->insams[0]] = dz->sampbuf[0][dz->insams[0] - 1]; /* wrap around point for interpolation */
- startsearch = (int)round(dz->param[RRR_START] * dz->infile->srate);
- endsearch = (int)round(dz->param[RRR_END] * dz->infile->srate);
- /* FIND ALL POSITIVE PEAKS : always look only at +ve vals, so all zero-crossings eventually found will be from +ve to -ve */
- peakcnt = 0;
- if((exit_status = find_all_positive_peaks(startsearch,endsearch,&peakcnt,dz)) < 0)
- return(exit_status);
- /* FIND ALL POSITIVE-PEAK MINIMA : overwriting the arrays peak-vals & peak-position with minima-vals & minima-positions */
- local_minima_cnt = 0;
- if((exit_status = find_all_local_minima(peakcnt,&local_minima_cnt,dz)) < 0)
- return(exit_status);
- /* ELIMINATE SPURIOUS MINIMA */
- if((exit_status = eliminate_spurious_minima(&local_minima_cnt,&minimum_element_len,dz)) < 0)
- return (exit_status);
- fprintf(stdout,"INFO: Original number of iterated segments found = %d\n",local_minima_cnt - 1);
- fflush(stdout);
- /* CHECK MINIMA FOUND AGAINST INPUT ESTIMATE */
- if((local_minima_cnt - 1) >= 2 * dz->iparam[RRR_GET]) {
- if((exit_status = eliminate_excess_minima(&local_minima_cnt,pos,dz)) < 0)
- return (exit_status);
- fprintf(stdout,"INFO: Reduced to = %d\n",local_minima_cnt - 1);
- fflush(stdout);
- }
- /* SEARCH FOR ZERO CROSSINGS AFTER MINIMA */
- if(local_minima_cnt > 999) {
- sprintf(errstr,"Found more than 999 segments. Process terminated.\n");
- return(GOAL_FAILED);
- }
- if((exit_status = locate_zero_crossings(local_minima_cnt,dz)) < 0)
- return (exit_status);
- /* COPY SOUND START TO OUTBUF */
- outpos = 0;
- if (pos[0] > 0) {
- fprintf(stdout,"INFO: Cutting start of sound\n");
- fflush(stdout);
- }
- if((exit_status = write_samps(obuf,pos[0],dz))<0)
- return(exit_status);
- outpos = pos[0];
- for (n = 1; n < local_minima_cnt; n++) {
- if((exit_status = headwrite(dz->ofd,dz))<0) {
- return(exit_status);
- }
- if(sndcloseEx(dz->ofd) < 0) {
- fprintf(stdout,"WARNING: Can't close output soundfile %s\n",outfilename);
- fflush(stdout);
- }
- z++;
- strcpy(outfilename,dz->wordstor[0]);
- if(!sloom)
- insert_new_number_at_filename_end(outfilename,n,0);
- else
- insert_new_number_at_filename_end(outfilename,n,1);
- if((exit_status = create_sized_outfile(outfilename,dz))<0) {
- sprintf(errstr,"WARNING: Can't create output soundfile %s\n",outfilename);
- return(SYSTEM_ERROR);
- }
- if(n==1) {
- fprintf(stdout,"INFO: Cutting each iterated segment\n");
- fflush(stdout);
- }
- obuf = dz->sampbuf[0] + outpos;
- samps_to_write = pos[n] - pos[n-1];
- if((exit_status = write_samps(obuf,samps_to_write,dz))<0)
- return(exit_status);
- outpos = pos[n];
- }
- if((exit_status = headwrite(dz->ofd,dz))<0) {
- free(outfilename);
- return(exit_status);
- }
- if(sndcloseEx(dz->ofd) < 0) {
- fprintf(stdout,"WARNING: Can't close output soundfile %s\n",outfilename);
- fflush(stdout);
- }
- z++;
- if(pos[n-1] < dz->insams[0]) {
- fprintf(stdout,"INFO: Cutting end of sound\n");
- fflush(stdout);
- strcpy(outfilename,dz->wordstor[0]);
- if(!sloom)
- insert_new_number_at_filename_end(outfilename,n,0);
- else
- insert_new_number_at_filename_end(outfilename,n,1);
- if((exit_status = create_sized_outfile(outfilename,dz))<0) {
- sprintf(errstr,"WARNING: Can't create output soundfile %s\n",outfilename);
- return(SYSTEM_ERROR);
- }
- obuf = dz->sampbuf[0] + outpos;
- samps_to_write = dz->insams[0] - pos[n-1];
- if((exit_status = write_samps(obuf,samps_to_write,dz))<0)
- return(exit_status);
- z++;
- }
- fprintf(stdout,"INFO: Total no of outfiles = %d\n",z);
- fflush(stdout);
- return(FINISHED);
- }
|