| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743 |
- /*
- * Copyright (c) 1983-2020 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>
- #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, 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;
- 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);
- }
|