cut.c 152 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758
  1. /*
  2. * Copyright (c) 1983-2023 Trevor Wishart and Composers Desktop Project Ltd
  3. * http://www.trevorwishart.co.uk
  4. * http://www.composersdesktop.com
  5. *
  6. This file is part of the CDP System.
  7. The CDP System is free software; you can redistribute it
  8. and/or modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  11. The CDP System is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU Lesser General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public
  16. License along with the CDP System; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18. 02111-1307 USA
  19. *
  20. */
  21. /* floatsam version*/
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <memory.h>
  25. #include <string.h>
  26. #include <structures.h>
  27. #include <tkglobals.h>
  28. #include <pnames.h>
  29. #include <flags.h>
  30. #include <globcon.h>
  31. #include <cdpmain.h>
  32. #include <edit.h>
  33. #include <modicon.h>
  34. #include <processno.h>
  35. #include <modeno.h>
  36. #include <logic.h>
  37. #include <flags.h>
  38. #include <arrays.h>
  39. #include <sfsys.h>
  40. #include <osbind.h>
  41. //#ifdef unix
  42. #define round(x) lround((x))
  43. //#endif
  44. #define UPSLOPE (0)
  45. #define DOWNSLOPE (1)
  46. #define IBUF (0)
  47. #define OBUF (1)
  48. #define SAVEBUF (1)
  49. #define SPLBUF (2)
  50. #define SPLBUF2 (3)
  51. #define BBUF (0)
  52. #define BUFEND (1)
  53. #define READBUF (2)
  54. #define SPLICEBUF (3)
  55. #define COPYBUF (4)
  56. #define ENDSPLICE_ADDR (3)
  57. #define CUTOFF_OUTPUT (0)
  58. #define JUST_CONTINUE (1)
  59. #define WRITERESTOF_INPUT (2)
  60. static int do_alternating_splices(int *in_noise,int *splice_cnt,int *edit_position,double splincr,dataptr dz);
  61. #define movmem(from, to, bytes) memcpy((to), (from), (bytes))
  62. static void setup_startcut_sector_offset(dataptr dz);
  63. static int create_cut_buffer(dataptr dz);
  64. static int create_zcut_buffer(dataptr dz);
  65. static int create_excise_buffers(dataptr dz);
  66. static int create_insert_buffers(dataptr dz);
  67. static int establish_working_chunks(dataptr dz);
  68. static void dosplice(float *buf, int samples, int chans, int invert);
  69. static int check_excise_splices(dataptr dz);
  70. static int find_zero(int end,int allsamps,dataptr dz);
  71. static int do_excise_finish(int obufleft,dataptr dz);
  72. static void crossplice(dataptr dz);
  73. static int do_excise_beginning(int *last_total_samps,int *obufleft,int k,dataptr dz);
  74. static int do_excise_ending(int *last_total_samps,int *obufleft,int *ibufleft,int k,dataptr dz);
  75. static int write_excise_end(int last_total_samps,int obufleft,int ibufleft,dataptr dz);
  76. static int copy_excise_chunk(int *last_total_samps,int *obufleft,int *ibufleft,int k,dataptr dz);
  77. static int gain_insert_buffer(float *thisbuf,int size,double gain);
  78. static void setup_excise_outdisplay_len(dataptr dz);
  79. static int join_pconsistency(dataptr dz);
  80. static int create_join_buffer(dataptr dz);
  81. static int create_join_seq_buffer(dataptr dz);
  82. static int read_join_splice_remnant(int n,int splice_remnant,int oversamps,dataptr dz);
  83. static void do_join_startsplice(int k,dataptr dz);
  84. static void do_join_initial_splice(int chans,dataptr dz);
  85. static void do_join_endsplice(dataptr dz);
  86. static void housekeep1(int samps_read,int overspill,dataptr dz);
  87. static void housekeep2(int samps_read,dataptr dz);
  88. static int do_join_write(int n,int splice_remnant,int oversamps,dataptr dz);
  89. static int reset_join_buffer_params(dataptr dz);
  90. int algo2;
  91. int do_insertsil_many(dataptr dz);
  92. void do_other_splice(float *buf, int splicelen, int start_in_splice, int end_in_splice, int chans, int invert);
  93. void ptr_sort(int end,dataptr dz);
  94. void heavy_scat(int stereo_splicelen,dataptr dz);
  95. void normal_scat(dataptr dz);
  96. int get_lengths(int stereo_splicelen,dataptr dz);
  97. void do_insitu_splice(int start,int end,int splicecnt,int chans,dataptr dz);
  98. void do_insitu_upsplice(int rel_bufstart,dataptr dz);
  99. //int create_an_outfile(int cutno, int cutlen, char *outfilename, char *outfilenumber, dataptr dz);
  100. int create_an_outfile(int cutno, int cutlen, char *outfilename, dataptr dz);
  101. int close_an_outfile(char *outfilename,dataptr dz);
  102. static int do_linear(dataptr dz,double,int,double), do_nonlinear(dataptr dz,double,int,double);
  103. static int do_fromstart(dataptr dz);
  104. static int cut_chunk(dataptr dz,double startcut,double endcut,int count);
  105. static void splice_obuf_start(float *obuf,dataptr dz);
  106. static void splice_obuf_end(float *obuf,int *splice_start,int startsamp,int endsamp,dataptr dz);
  107. static int setup_insert2_overwrite_flag(dataptr dz);
  108. static int silent_end;
  109. /******************************** EDIT_PCONSISTENCY ********************************/
  110. int edit_pconsistency(dataptr dz)
  111. {
  112. int exit_status;
  113. int chans = dz->infile->channels, k;
  114. double sr = (double)dz->infile->srate;
  115. int zz, zsecs;
  116. algo2 = 0;
  117. silent_end = 0;
  118. switch(dz->process) {
  119. case(EDIT_JOIN):
  120. case(JOIN_SEQ):
  121. case(JOIN_SEQDYN):
  122. return join_pconsistency(dz);
  123. case(EDIT_ZCUT): /* check for stereo file: no splicelen data: REALLY UNNECESSARY */
  124. if(chans!=MONO) {
  125. sprintf(errstr,"This process only works for MONO files.\n");
  126. return(DATA_ERROR);
  127. }
  128. break;
  129. default: /* establish splicelen constants */
  130. dz->iparam[CUT_SPLEN] = round(dz->param[CUT_SPLEN] * MS_TO_SECS * sr) * chans;
  131. break;
  132. }
  133. if(dz->process!=EDIT_EXCISEMANY && dz->process!=INSERTSIL_MANY) {
  134. switch(dz->mode) { /* read cutstart info, and convert to samps: info in file for EXCISEMANY */
  135. case(EDIT_SECS):
  136. dz->iparam[CUT_CUT] = round(dz->param[CUT_CUT] * sr) * chans;
  137. break;
  138. case(EDIT_SAMPS):
  139. dz->iparam[CUT_CUT] = (dz->iparam[CUT_CUT]/chans) * chans; /* align to sample-group boundary */
  140. break;
  141. case(EDIT_STSAMPS):
  142. dz->iparam[CUT_CUT] *= chans;
  143. break;
  144. }
  145. }
  146. switch(dz->process) {
  147. case(EDIT_CUT): /* read cutend or cutdur info, and convert to samps */
  148. case(EDIT_ZCUT):
  149. case(EDIT_EXCISE):
  150. case(EDIT_INSERTSIL):
  151. switch(dz->mode) {
  152. case(EDIT_SECS):
  153. dz->iparam[CUT_END] = round(dz->param[CUT_END] * sr) * chans;
  154. break;
  155. case(EDIT_SAMPS):
  156. dz->iparam[CUT_END] = (dz->iparam[CUT_END]/chans) * chans; /* align to sample-group boundary */
  157. break;
  158. case(EDIT_STSAMPS):
  159. dz->iparam[CUT_END] *= chans;
  160. break;
  161. }
  162. break;
  163. case(EDIT_INSERT2):
  164. dz->iparam[CUT_END] = round(dz->param[CUT_END] * sr) * chans;
  165. if((exit_status = setup_insert2_overwrite_flag(dz))<0)
  166. return(exit_status);
  167. break;
  168. }
  169. switch(dz->process) {
  170. case(EDIT_CUT): /* check consistency cutstart & cutend data */
  171. case(EDIT_ZCUT):
  172. case(EDIT_EXCISE):
  173. if(dz->iparam[CUT_END] == dz->iparam[CUT_CUT]) {
  174. sprintf(errstr,"endcut = startcut: No cutting possible.\n");
  175. return(DATA_ERROR);
  176. }
  177. if(dz->iparam[CUT_END] < dz->iparam[CUT_CUT]) {
  178. fprintf(stdout,"WARNING: end cut before startcut: reversing these times.\n");
  179. fflush(stdout);
  180. iiswap(&(dz->iparam[CUT_END]),&(dz->iparam[CUT_CUT]));
  181. }
  182. break;
  183. }
  184. switch(dz->process) { /* establish cutlen: check mutual consistency of params, for process */
  185. case(EDIT_INSERTSIL):
  186. dz->iparam[CUT_LEN] = dz->iparam[CUT_END];
  187. if(dz->iparam[CUT_SPLEN] * 2 > dz->iparam[CUT_LEN]) {
  188. sprintf(errstr,"Inserted silence is too short for splices.\n");
  189. return(GOAL_FAILED);
  190. }
  191. if(dz->vflag[INSERT_OVERWRITE]
  192. && (dz->iparam[CUT_CUT] + dz->iparam[CUT_LEN] - dz->iparam[CUT_SPLEN] >= dz->insams[0])) {
  193. if(dz->vflag[ACCEPT_SILENT_END]) {
  194. silent_end = 1;
  195. fprintf(stdout,"WARNING: Insertion will cut sound at end of file: leaving a silent section there.\n");
  196. fflush(stdout);
  197. } else {
  198. if(sloom)
  199. sprintf(errstr,"Insertion will cut off entire end of file: use EDIT : CUTOUT & KEEP\n");
  200. else
  201. sprintf(errstr,"Insertion will cut off entire end of file: use sfedit cut\n");
  202. return(GOAL_FAILED);
  203. }
  204. }
  205. if(dz->iparam[CUT_CUT] < dz->iparam[CUT_SPLEN]) {
  206. sprintf(errstr,"Insert time too close to start of file (allowing for splice)\n");
  207. return(GOAL_FAILED);
  208. }
  209. if(dz->iparam[CUT_CUT] >= dz->insams[0] - dz->iparam[CUT_SPLEN]) {
  210. if(dz->vflag[INSERT_OVERWRITE] || (dz->iparam[CUT_LEN] <= dz->iparam[CUT_SPLEN])) {
  211. sprintf(errstr,"Insert time beyond end of infile (allowing for splice)\n");
  212. return(GOAL_FAILED);
  213. } else {
  214. dz->tempsize = dz->insams[0] + dz->iparam[CUT_CUT];
  215. algo2 = 1;
  216. return(FINISHED);
  217. }
  218. }
  219. if(dz->vflag[INSERT_OVERWRITE])
  220. dz->tempsize = dz->insams[0];
  221. else
  222. dz->tempsize = dz->insams[0] + dz->insams[1] - (dz->iparam[CUT_SPLEN] * 2);
  223. break;
  224. case(INSERTSIL_MANY):
  225. dz->tempsize = dz->insams[0];
  226. algo2 = 1;
  227. break;
  228. case(EDIT_INSERT2):
  229. if(dz->iparam[CUT_END] >= dz->insams[0] - dz->iparam[CUT_SPLEN]) {
  230. sprintf(errstr,"Overwrite endtime is beyond end of infile (allowing for splice)\n");
  231. return(GOAL_FAILED);
  232. }
  233. /*fall thro */
  234. case(EDIT_INSERT):
  235. if(dz->iparam[CUT_CUT] < dz->iparam[CUT_SPLEN]) {
  236. sprintf(errstr,"Insert time too close to start of file (allowing for splice)\n");
  237. return(GOAL_FAILED);
  238. }
  239. if(dz->iparam[CUT_CUT] >= dz->insams[0] - dz->iparam[CUT_SPLEN]) {
  240. sprintf(errstr,"Insert time beyond end of infile (allowing for splice)\n");
  241. return(GOAL_FAILED);
  242. }
  243. if((dz->process == EDIT_INSERT) && dz->vflag[INSERT_OVERWRITE]
  244. && (dz->iparam[CUT_CUT] + dz->insams[1] - dz->iparam[CUT_SPLEN] >= dz->insams[0])) {
  245. sprintf(errstr,"Insertion will cut off whole end of first file: use cut and splice.\n");
  246. return(GOAL_FAILED);
  247. }
  248. if(dz->iparam[CUT_SPLEN] * 2 > dz->insams[1]) {
  249. sprintf(errstr,"Inserted file is too short for splices.\n");
  250. return(GOAL_FAILED);
  251. }
  252. if((dz->process == EDIT_INSERT) && dz->vflag[INSERT_OVERWRITE])
  253. dz->tempsize = dz->insams[0];
  254. else
  255. dz->tempsize = dz->insams[0] + dz->insams[1] - (dz->iparam[CUT_SPLEN] * 2);
  256. break;
  257. case(EDIT_CUT):
  258. case(EDIT_EXCISE):
  259. dz->iparam[CUT_LEN] = dz->iparam[CUT_END] - dz->iparam[CUT_CUT];
  260. dz->tempsize = dz->iparam[CUT_LEN]; /* EDIT_CUT only : EDIT_EXCISE reset below */
  261. if((dz->iparam[CUT_SPLEN] * 2) > dz->iparam[CUT_LEN]) {
  262. sprintf(errstr,"Edited portion is too short for specified splicelen.\n");
  263. return(GOAL_FAILED);
  264. }
  265. break;
  266. case(EDIT_CUTEND):
  267. dz->tempsize = dz->iparam[CUT_CUT];
  268. dz->iparam[CUT_CUT] = dz->insams[0] - dz->iparam[CUT_CUT];
  269. if(dz->iparam[CUT_CUT] >= dz->insams[0] - (2 * dz->iparam[CUT_SPLEN])) {
  270. sprintf(errstr,"Edited portion is too short for specified splicelen.\n");
  271. return(GOAL_FAILED);
  272. }
  273. dz->iparam[CUT_END] = dz->insams[0];
  274. dz->iparam[CUT_LEN] = dz->iparam[CUT_END] - dz->iparam[CUT_CUT];
  275. break;
  276. case(EDIT_ZCUT):
  277. if(dz->iparam[CUT_END] > dz->insams[0]) {
  278. fprintf(stdout,"WARNING: Assumed end of cut [%.2lf] is end of file [%.2lf]\n",
  279. dz->param[CUT_END],(double)(dz->insams[0]/chans)/sr);
  280. fflush(stdout);
  281. dz->iparam[CUT_END] = dz->insams[0];
  282. }
  283. dz->tempsize = dz->iparam[CUT_END] - dz->iparam[CUT_CUT];
  284. if(dz->iparam[CUT_END]== dz->insams[0])
  285. dz->iparam[CUT_GOES_TO_END] = TRUE;
  286. else
  287. dz->iparam[CUT_GOES_TO_END] = FALSE;
  288. break;
  289. }
  290. switch(dz->process) { /* setup extra arrays or internal variables */
  291. case(EDIT_EXCISE):
  292. dz->iparam[EXCISE_CNT] = 1;
  293. dz->iparam[CUT_NO_END] = FALSE;
  294. if((dz->lparray[CUT_STTSAMP] = (int *)malloc(sizeof(int)))==NULL
  295. || (dz->lparray[CUT_STTSPLI] = (int *)malloc(sizeof(int)))==NULL
  296. || (dz->lparray[CUT_ENDSAMP] = (int *)malloc(sizeof(int)))==NULL
  297. || (dz->lparray[CUT_ENDSPLI] = (int *)malloc(sizeof(int)))==NULL) {
  298. sprintf(errstr,"INSUFFICIENT_MEMORY to store excise times.\n");
  299. return(MEMORY_ERROR);
  300. }
  301. dz->lparray[CUT_STTSAMP][0] = dz->iparam[CUT_CUT];
  302. dz->lparray[CUT_ENDSAMP][0] = dz->iparam[CUT_END];
  303. /* fall thro */
  304. case(INSERTSIL_MANY):
  305. case(EDIT_EXCISEMANY):
  306. /* It's values were read from a file by special */
  307. zz = chans * 2;
  308. zsecs = dz->iparam[CUT_SPLEN]/zz;
  309. if(zsecs * zz != dz->iparam[CUT_SPLEN]) {
  310. zsecs++;
  311. }
  312. dz->iparam[CUT_SPLEN] = zsecs * zz;
  313. dz->iparam[CUT_HLFSPLEN] = dz->iparam[CUT_SPLEN]/2; /* hence hlfsplen is whole no. chans */
  314. if(dz->infile->channels>MONO) {
  315. for(k=0;k<dz->iparam[EXCISE_CNT];k++) { /* align to samp-grp boundaries */
  316. dz->lparray[CUT_STTSAMP][k] = (dz->lparray[CUT_STTSAMP][k]/chans) * chans;
  317. dz->lparray[CUT_ENDSAMP][k] = (dz->lparray[CUT_ENDSAMP][k]/chans) * chans;
  318. }
  319. }
  320. if((exit_status = check_excise_splices(dz))<0)
  321. return(exit_status);
  322. setup_excise_outdisplay_len(dz);
  323. break;
  324. case(EDIT_CUT):
  325. case(EDIT_CUTEND):
  326. setup_startcut_sector_offset(dz);
  327. break;
  328. }
  329. return(FINISHED);
  330. }
  331. /******************************** EDIT_PREPROCESS ********************************/
  332. int edit_preprocess(dataptr dz)
  333. {
  334. int shsecsize = F_SECSIZE; /* RWD want to eliminate this... */
  335. switch(dz->process) {
  336. case(EDIT_CUT):
  337. case(EDIT_CUTEND):
  338. return establish_working_chunks(dz);
  339. case(EDIT_INSERT2):
  340. case(EDIT_INSERT):
  341. case(EDIT_INSERTSIL):
  342. if(algo2)
  343. break;
  344. dz->iparam[CUT_BUFXS] = (dz->iparam[CUT_CUT] - dz->iparam[CUT_SPLEN]) % F_SECSIZE;
  345. dz->iparam[CUT_BUFREMNANT] =
  346. (dz->iparam[CUT_SECSREMAIN] * shsecsize) - (dz->iparam[CUT_BUFXS] + dz->iparam[CUT_SPLEN]);
  347. break;
  348. }
  349. return(FINISHED);
  350. }
  351. /******************************** SETUP_SECTOR_OFFSET_PARAMS ********************************/
  352. void setup_startcut_sector_offset(dataptr dz)
  353. {
  354. dz->iparam[CUT_BUFXS] = dz->iparam[CUT_CUT] % F_SECSIZE;
  355. dz->iparam[CUT_BUFOFFSET] = F_SECSIZE - dz->iparam[CUT_BUFXS];
  356. }
  357. /******************************** CREATE_EDIT_BUFFERS ********************************/
  358. int create_edit_buffers(dataptr dz)
  359. {
  360. int exit_status;
  361. switch(dz->process) {
  362. case(EDIT_CUT):
  363. case(EDIT_CUTEND):
  364. case(RANDCHUNKS): exit_status = create_cut_buffer(dz); break;
  365. case(MANY_ZCUTS):
  366. case(EDIT_ZCUT): exit_status = create_zcut_buffer(dz); break;
  367. case(EDIT_EXCISE):
  368. case(EDIT_EXCISEMANY): exit_status = create_excise_buffers(dz); break;
  369. case(EDIT_INSERT):
  370. case(EDIT_INSERT2):
  371. case(INSERTSIL_MANY):
  372. case(EDIT_INSERTSIL): exit_status = create_insert_buffers(dz); break;
  373. case(JOIN_SEQDYN):
  374. case(JOIN_SEQ): exit_status = create_join_seq_buffer(dz); break;
  375. case(EDIT_JOIN): exit_status = create_join_buffer(dz); break;
  376. default:
  377. sprintf(errstr,"Unknown process in create_edit_buffers()\n");
  378. return(PROGRAM_ERROR);
  379. }
  380. return(exit_status);
  381. }
  382. /******************************** CREATE_CUT_BUFFER ********************************/
  383. int create_cut_buffer(dataptr dz)
  384. {
  385. size_t bigbufsize;
  386. int secsize, sectorsize = dz->infile->channels * F_SECSIZE;
  387. bigbufsize = (size_t)Malloc(-1);
  388. bigbufsize /= sizeof(float);
  389. bigbufsize = (bigbufsize / sectorsize) * sectorsize;
  390. if(bigbufsize < dz->iparam[CUT_SPLEN]) {
  391. bigbufsize = dz->iparam[CUT_SPLEN] + sectorsize;
  392. secsize = bigbufsize / sectorsize;
  393. if(secsize * sectorsize != bigbufsize)
  394. secsize++;
  395. bigbufsize = secsize * sectorsize;
  396. }
  397. if(bigbufsize <= F_SECSIZE ){
  398. sprintf(errstr, "INSUFFICIENT MEMORY for sound.\n");
  399. return(MEMORY_ERROR);
  400. }
  401. dz->iparam[SMALLBUFSIZ] = bigbufsize - F_SECSIZE;
  402. if((dz->bigbuf = (float *)Malloc(bigbufsize * sizeof(float))) == 0) {
  403. sprintf(errstr, "INSUFFICIENT MEMORY for sound.\n");
  404. return(MEMORY_ERROR);
  405. }
  406. dz->buflen = (int) bigbufsize; /*RWD*/
  407. return(FINISHED);
  408. }
  409. /******************************** CREATE_ZCUT_BUFFER ********************************/
  410. int create_zcut_buffer(dataptr dz)
  411. {
  412. /* RWD this may still all be dodgy for n-channel work!*/
  413. size_t bigbufsize;
  414. int secextra = F_SECSIZE;
  415. // secextra = (secextra / dz->infile->channels) * dz->infile->channels;
  416. if((secextra = (secextra / dz->infile->channels) * dz->infile->channels)<=0) {
  417. sprintf(errstr,"Can't handle this many channels.\n");
  418. return(DATA_ERROR);
  419. }
  420. bigbufsize = (size_t)Malloc(-1);
  421. bigbufsize /= sizeof(float);
  422. bigbufsize = (bigbufsize/F_SECSIZE) * F_SECSIZE;
  423. if((dz->bigbuf = (float *)Malloc((bigbufsize + secextra) * sizeof(float))) == NULL) {
  424. sprintf(errstr, "INSUFFICIENT MEMORY for sound.\n");
  425. return(MEMORY_ERROR);
  426. }
  427. dz->buflen = (int) bigbufsize;
  428. dz->sampbuf[OBUF] = dz->sampbuf[IBUF] = dz->bigbuf + secextra;
  429. return(FINISHED);
  430. }
  431. /******************************** CREATE_EXCISE_BUFFERS ********************************/
  432. int create_excise_buffers(dataptr dz)
  433. {
  434. size_t bigbufsize, framesize;
  435. int splicespace = 2 * dz->iparam[CUT_SPLEN];
  436. //TW : again algo depends on this SECSIZE structuring, at present
  437. // framesize = dz->infile->channels;
  438. framesize = dz->infile->channels * F_SECSIZE * 2;
  439. bigbufsize = (size_t) Malloc(-1) / sizeof(float);
  440. bigbufsize = (bigbufsize/framesize) * framesize;
  441. bigbufsize /= 2;
  442. if(bigbufsize<=0) {
  443. sprintf(errstr, "INSUFFICIENT MEMORY for sound.\n");
  444. return(MEMORY_ERROR);
  445. }
  446. if((dz->bigbuf = (float *) Malloc(((bigbufsize * 2) + splicespace) * sizeof(float)))==0) {
  447. sprintf(errstr, "INSUFFICIENT MEMORY for sound.\n");
  448. return(MEMORY_ERROR);
  449. }
  450. dz->buflen = (int) bigbufsize;
  451. dz->sbufptr[IBUF] = dz->sampbuf[IBUF] = dz->bigbuf;
  452. dz->sbufptr[OBUF] = dz->sampbuf[OBUF] = dz->sampbuf[IBUF] + dz->buflen;
  453. dz->sbufptr[SPLBUF] = dz->sampbuf[SPLBUF] = dz->sampbuf[OBUF] + dz->buflen;
  454. dz->sbufptr[SPLBUF2] = dz->sampbuf[SPLBUF2] = dz->sampbuf[SPLBUF] + dz->iparam[CUT_SPLEN];
  455. memset((char *)dz->sampbuf[SPLBUF],0,dz->iparam[CUT_SPLEN]* sizeof(float));
  456. return FINISHED;
  457. }
  458. /******************************** CREATE_INSERT_BUFFERS ********************************/
  459. int create_insert_buffers(dataptr dz)
  460. {
  461. size_t bigbufsize;
  462. int splice_space = dz->iparam[CUT_SPLEN] + F_SECSIZE; /* Allow for splice-end not aligning to sector boundary */
  463. int prelen = dz->iparam[CUT_CUT] - dz->iparam[CUT_SPLEN];
  464. int prelen2, splicebuf_samplen, insertsize;
  465. float *cp;
  466. int framesize = dz->infile->channels * F_SECSIZE * 2;
  467. bigbufsize = (size_t) Malloc(-1);
  468. /*RWD*/
  469. dz->buflen = (bigbufsize / framesize) * framesize;
  470. if(algo2) {
  471. if((dz->bigbuf = (float *)Malloc(dz->buflen * sizeof(float))) == 0) {
  472. sprintf(errstr, "INSUFFICIENT MEMORY.\n");
  473. return(MEMORY_ERROR);
  474. } else {
  475. return(FINISHED);
  476. }
  477. }
  478. dz->iparam[SMALLBUFSIZ] = /*dz->bigbufsize - SECSIZE;*/ dz->buflen - F_SECSIZE;
  479. if(dz->iparam[SMALLBUFSIZ] < splice_space) {
  480. sprintf(errstr,"INSUFFICIENT MEMORY for sound.\n");
  481. return(MEMORY_ERROR);
  482. }
  483. dz->iparam[CUT_BUFCNT] = prelen/dz->buflen; /* no. of whole buffers in sfile, before splice */
  484. dz->iparam[CUT_SECCNT] = (prelen%dz->buflen)/F_SECSIZE; /* no. whole sectors remaining, before splice */
  485. dz->iparam[CUT_SMPSREMAIN] =
  486. dz->iparam[CUT_CUT] - ((dz->iparam[CUT_BUFCNT] * dz->buflen) + (dz->iparam[CUT_SECCNT] * F_SECSIZE));
  487. /* remainder of file */
  488. dz->iparam[CUT_SECSREMAIN] = dz->iparam[CUT_SMPSREMAIN]/F_SECSIZE;
  489. if(dz->iparam[CUT_SECSREMAIN] * F_SECSIZE != dz->iparam[CUT_SMPSREMAIN])
  490. dz->iparam[CUT_SECSREMAIN]++; /* GROSS number of sectors in remainder of file */
  491. if(dz->iparam[CUT_SECSREMAIN] * F_SECSIZE > dz->buflen) {
  492. sprintf(errstr,"INSUFFICIENT MEMORY for sound.\n");
  493. return(MEMORY_ERROR);
  494. }
  495. switch(dz->process) {
  496. case(EDIT_INSERT): insertsize = dz->insams[1]; break;
  497. case(EDIT_INSERT2): insertsize = dz->insams[1]; break;
  498. case(EDIT_INSERTSIL): insertsize = dz->iparam[CUT_LEN]; break;
  499. default:
  500. sprintf(errstr,"Unknown process in create_insert_buffers()\n");
  501. return(PROGRAM_ERROR);
  502. }
  503. prelen2 = insertsize - splice_space;
  504. dz->iparam[CUT_BUFCNT2] = prelen2/dz->iparam[SMALLBUFSIZ]; /* no. whole bufs in insertfile, before splice */
  505. dz->iparam[CUT_SECCNT2] = (prelen2%dz->iparam[SMALLBUFSIZ])/F_SECSIZE; /* no. whole secs remaining, before splice */
  506. dz->iparam[CUT_SMPSREMAIN] = /* remainder of file */
  507. insertsize - ((dz->iparam[CUT_BUFCNT2] * dz->iparam[SMALLBUFSIZ]) + (dz->iparam[CUT_SECCNT2] * F_SECSIZE));
  508. dz->iparam[CUT_SECSREMAIN2] = dz->iparam[CUT_SMPSREMAIN]/F_SECSIZE;
  509. if(dz->iparam[CUT_SECSREMAIN2] * F_SECSIZE != dz->iparam[CUT_SMPSREMAIN])
  510. dz->iparam[CUT_SECSREMAIN2]++; /* GROSS no. of sectors in remainder of file */
  511. if((dz->iparam[CUT_SECSREMAIN2] + 1) * F_SECSIZE > dz->buflen) {
  512. sprintf(errstr,"Buffers too small for splice.\n");
  513. return(MEMORY_ERROR);
  514. }
  515. splicebuf_samplen = (dz->iparam[CUT_SECSREMAIN] + 2) * F_SECSIZE;
  516. if((cp = dz->bigbuf = (float *)malloc(sizeof(float) * (dz->buflen + (splicebuf_samplen * 2)))) == NULL) {
  517. sprintf(errstr,"INSUFFICIENT MEMORY for sound.\n");
  518. return(MEMORY_ERROR);
  519. }
  520. dz->sampbuf[0] = dz->bigbuf;
  521. dz->sampbuf[SPLBUF] = dz->sampbuf[0] + dz->buflen;
  522. dz->sampbuf[SAVEBUF] = dz->sampbuf[SPLBUF] + (splicebuf_samplen);
  523. memset((char *)dz->sampbuf[SAVEBUF],0,splicebuf_samplen * sizeof(float));
  524. memset((char *)dz->sampbuf[SPLBUF], 0,splicebuf_samplen * sizeof(float));
  525. return(FINISHED);
  526. }
  527. /******************************** ESTABLISH_WORKING_CHUNKS ********************************
  528. *
  529. * (2) SPLICE_SPACE: number of sectors definitely containing the endsplice of the cut.
  530. * (3) PRELEN: No of samps in file from end of last complete sector BEFORE cut, to a point
  531. * definitely before final splice starts.
  532. * (4) LOPOFF: Counts up number of samps to read, from end of preliminary seek to BEFORE endsplice area.
  533. * (5) CUT_SECSREMAIN: Final number of sectors to read, containing all of the final splice.
  534. */
  535. int establish_working_chunks(dataptr dz)
  536. {
  537. /* OLD **/
  538. int splice_space = dz->iparam[CUT_SPLEN] + F_SECSIZE; /* 2 */
  539. int prelen = dz->iparam[CUT_LEN] + dz->iparam[CUT_BUFXS] - splice_space; /* 3 */
  540. int lopoff = 0; /* 4 */
  541. int OK = 0;
  542. while (!OK) {
  543. /* count number of whole BUFFERS to read */
  544. dz->iparam[CUT_BUFCNT] = 0;
  545. if(prelen >= dz->buflen) { /* 1st attempt to read a whole buffer, reads dz->bigbufsize */
  546. dz->iparam[CUT_BUFCNT]++;
  547. prelen -= dz->buflen;
  548. lopoff += dz->buflen;
  549. while(prelen >= dz->iparam[SMALLBUFSIZ]) { /* subsequent attempts read a smbuffsz, allowing for wraparound */
  550. dz->iparam[CUT_BUFCNT]++;
  551. prelen -= dz->iparam[SMALLBUFSIZ];
  552. lopoff += dz->iparam[SMALLBUFSIZ];
  553. }
  554. }
  555. /* count number of whole SECTORS to read */
  556. dz->iparam[CUT_SECCNT] = 0;
  557. while(prelen >= F_SECSIZE) {
  558. dz->iparam[CUT_SECCNT]++;
  559. prelen -= F_SECSIZE;
  560. lopoff += F_SECSIZE;
  561. } /* calculate final no. samples left to read */
  562. dz->iparam[CUT_SMPSREMAIN] = dz->iparam[CUT_LEN] + dz->iparam[CUT_BUFXS] - lopoff;
  563. dz->iparam[CUT_SECSREMAIN] = dz->iparam[CUT_SMPSREMAIN] / F_SECSIZE;
  564. if(dz->iparam[CUT_SECSREMAIN] * F_SECSIZE != dz->iparam[CUT_SMPSREMAIN]) /* 5 */
  565. dz->iparam[CUT_SECSREMAIN]++; /* GROSS number of sectors in remainder of file */
  566. if(dz->iparam[CUT_SECSREMAIN] * F_SECSIZE > dz->buflen) { /* Possibly unnnecessary check: but being safe */
  567. dz->iparam[SMALLBUFSIZ] = dz->buflen;
  568. dz->buflen += F_SECSIZE;
  569. if((dz->bigbuf = (float *)realloc((char *)dz->bigbuf,dz->buflen * sizeof(float)))==NULL) {
  570. sprintf(errstr, "INSUFFICIENT MEMORY for endsplice.\n");
  571. return(MEMORY_ERROR);
  572. }
  573. } else
  574. OK = 1;
  575. }
  576. return(FINISHED);
  577. }
  578. /******************************** DO_CUT ********************************/
  579. int do_cut(dataptr dz)
  580. {
  581. int exit_status;
  582. int ref, cc, to_write = 0, seektest;
  583. int first = 1;
  584. float *bufptr = dz->bigbuf; /* CUrrent buffer pointer */
  585. int shsecsize = F_SECSIZE, samps_read;
  586. int is_startcut = TRUE;
  587. if(dz->process==EDIT_CUT && dz->iparam[CUT_CUT]==0)
  588. is_startcut = FALSE;
  589. /* seek to start of sector before cut */
  590. if((seektest = sndseekEx(dz->ifd[0], (dz->iparam[CUT_CUT] / F_SECSIZE) * F_SECSIZE, 0))
  591. != (dz->iparam[CUT_CUT] / F_SECSIZE) * F_SECSIZE) {
  592. if(seektest<0) {
  593. sprintf(errstr,"sndseekEx() failed.\n");
  594. return(SYSTEM_ERROR);
  595. } else {
  596. sprintf(errstr,"Start time after end of file.\n");
  597. return(PROGRAM_ERROR);
  598. }
  599. }
  600. /* ANY WHOLE BUFFERS OF CUT ARE COPIED */
  601. ref = dz->iparam[SMALLBUFSIZ];
  602. for(cc = 1; cc <= dz->iparam[CUT_BUFCNT]; cc++) {
  603. if(first) {
  604. first = 0;
  605. if((samps_read = fgetfbufEx(dz->bigbuf, dz->buflen,dz->ifd[0],0))!=dz->buflen) {
  606. sprintf(errstr,"Bad sound read 1.\n");
  607. if(samps_read<0)
  608. return(SYSTEM_ERROR);
  609. return(PROGRAM_ERROR);
  610. }
  611. bufptr += dz->iparam[CUT_BUFXS]; /* reset input-pointer to start of cut */
  612. if(dz->iparam[CUT_SPLEN] > 0 && is_startcut)
  613. dosplice(bufptr, dz->iparam[CUT_SPLEN], dz->infile->channels, UPSLOPE);
  614. if((exit_status = write_exact_samps(bufptr, dz->iparam[SMALLBUFSIZ],dz))<0)
  615. return(exit_status);
  616. bufptr += ref;
  617. memcpy((char *)dz->bigbuf, (char *)bufptr,
  618. dz->iparam[CUT_BUFOFFSET] * sizeof(float));
  619. bufptr = dz->bigbuf + dz->iparam[CUT_BUFOFFSET];
  620. } else {
  621. if((samps_read = fgetfbufEx(bufptr, dz->iparam[SMALLBUFSIZ],dz->ifd[0],0))!=dz->iparam[SMALLBUFSIZ]) {
  622. sprintf(errstr,"Bad sound read 2.\n");
  623. if(samps_read<0)
  624. return(SYSTEM_ERROR);
  625. return(PROGRAM_ERROR);
  626. }
  627. if((exit_status = write_exact_samps(dz->bigbuf, dz->iparam[SMALLBUFSIZ],dz))<0)
  628. return(exit_status);
  629. bufptr = dz->bigbuf + ref;
  630. memcpy((char *)dz->bigbuf, (char *)bufptr,
  631. dz->iparam[CUT_BUFOFFSET] * sizeof(float));
  632. bufptr = dz->bigbuf + dz->iparam[CUT_BUFOFFSET];
  633. }
  634. }
  635. /* ANY (FURTHER) WHOLE SECTORS BEFORE ENDSPLICE, ARE COPIED */
  636. if(dz->iparam[CUT_SECCNT]) {
  637. if(first) {
  638. first = 0;
  639. if((samps_read =
  640. fgetfbufEx(dz->bigbuf, dz->iparam[CUT_SECCNT] * F_SECSIZE,dz->ifd[0],0))!=dz->iparam[CUT_SECCNT] * F_SECSIZE) {
  641. sprintf(errstr,"Bad sound read 3.\n");
  642. if(samps_read<0)
  643. return(SYSTEM_ERROR);
  644. return(PROGRAM_ERROR);
  645. }
  646. bufptr += dz->iparam[CUT_BUFXS]; /* reset input-pointer to start of cut */
  647. if(dz->iparam[CUT_SPLEN]>0 && is_startcut)
  648. /* splice beginning of input */
  649. dosplice(bufptr, dz->iparam[CUT_SPLEN],dz->infile->channels, UPSLOPE);
  650. dz->iparam[CUT_SECCNT]--;
  651. if(dz->iparam[CUT_SECCNT]) {
  652. if((exit_status = write_exact_samps(bufptr, dz->iparam[CUT_SECCNT] * F_SECSIZE,dz))<0)
  653. return(exit_status);
  654. }
  655. bufptr += dz->iparam[CUT_SECCNT] * shsecsize;
  656. memcpy((char *)dz->bigbuf, (char *)bufptr,
  657. dz->iparam[CUT_BUFOFFSET] * sizeof(float));
  658. bufptr = dz->bigbuf + dz->iparam[CUT_BUFOFFSET];
  659. } else {
  660. if((samps_read =
  661. fgetfbufEx(bufptr,dz->iparam[CUT_SECCNT] * F_SECSIZE,dz->ifd[0],0))
  662. != dz->iparam[CUT_SECCNT] * F_SECSIZE) {
  663. sprintf(errstr,"Bad sound read 4.\n");
  664. if(samps_read<0)
  665. return(SYSTEM_ERROR);
  666. return(PROGRAM_ERROR);
  667. }
  668. if(dz->iparam[CUT_SECCNT]) {
  669. if((exit_status = write_exact_samps(dz->bigbuf,dz->iparam[CUT_SECCNT] * F_SECSIZE,dz))<0)
  670. return(exit_status);
  671. }
  672. bufptr = dz->bigbuf + (dz->iparam[CUT_SECCNT] * shsecsize);
  673. memcpy((char *)dz->bigbuf, (char *)bufptr,
  674. dz->iparam[CUT_BUFOFFSET] * sizeof(float));
  675. bufptr = dz->bigbuf + dz->iparam[CUT_BUFOFFSET];
  676. }
  677. }
  678. /* DO SECTORS CONTAINING ENDSPLICE OF CUT */
  679. if(first) { /* IF THERE ARE NO WHOLE BUFFERS OR SECTORS BEFORE SPLICE STARTS */
  680. if((samps_read = fgetfbufEx(dz->bigbuf, dz->iparam[CUT_SECSREMAIN] * F_SECSIZE,dz->ifd[0],0))<=0) {
  681. sprintf(errstr,"Bad sound read 5.\n");
  682. if(samps_read<0)
  683. return(SYSTEM_ERROR);
  684. return(PROGRAM_ERROR);
  685. }
  686. bufptr += dz->iparam[CUT_BUFXS]; /* reset input-pointer to start of cut */
  687. if(dz->iparam[CUT_SPLEN] > 0) { /* splice beginning (& end if not CUTEND) of file */
  688. if(is_startcut)
  689. dosplice(bufptr, dz->iparam[CUT_SPLEN],dz->infile->channels, UPSLOPE);
  690. bufptr = dz->bigbuf + dz->iparam[CUT_SMPSREMAIN] - dz->iparam[CUT_SPLEN];
  691. if(dz->process==EDIT_CUT)
  692. dosplice(bufptr, dz->iparam[CUT_SPLEN],dz->infile->channels, DOWNSLOPE);
  693. }
  694. bufptr = dz->bigbuf + dz->iparam[CUT_BUFXS];
  695. if(dz->iparam[CUT_LEN] > 0) {
  696. if((exit_status = write_samps(bufptr, dz->iparam[CUT_LEN],dz))<0)
  697. return(exit_status);
  698. }
  699. } else {
  700. if((samps_read = fgetfbufEx(bufptr, dz->iparam[CUT_SECSREMAIN] * F_SECSIZE,dz->ifd[0],0))<=0) {
  701. sprintf(errstr,"Bad sound read 6.\n");
  702. if(samps_read<0)
  703. return(SYSTEM_ERROR);
  704. return(PROGRAM_ERROR);
  705. }
  706. switch(dz->process) {
  707. case(EDIT_CUT):
  708. if(dz->iparam[CUT_SPLEN] > 0) {
  709. bufptr += dz->iparam[CUT_SMPSREMAIN] - dz->iparam[CUT_SPLEN];
  710. dosplice(bufptr, dz->iparam[CUT_SPLEN],dz->infile->channels, DOWNSLOPE);
  711. }
  712. to_write = dz->iparam[CUT_BUFOFFSET] + dz->iparam[CUT_SMPSREMAIN];
  713. break;
  714. case(EDIT_CUTEND):
  715. to_write = dz->iparam[CUT_BUFOFFSET] + samps_read;
  716. break;
  717. }
  718. if(to_write > 0) {
  719. if((exit_status = write_samps(dz->bigbuf,to_write,dz))<0)
  720. return(exit_status);
  721. }
  722. }
  723. return(FINISHED);
  724. }
  725. /******************************** DOSPLICE ********************************
  726. *
  727. * INVERT is flag to invert the direction of splice
  728. * 0 = normal, 1 = inverted
  729. */
  730. void dosplice(float *buf, int samples, int chans, int invert)
  731. {
  732. double a1 = 0.0, aincr;
  733. register int i, j;
  734. int sampgrps = samples/chans;
  735. aincr = 1.0/sampgrps;
  736. if(invert) {
  737. aincr = -aincr;
  738. a1 = 1.0 + aincr;
  739. }
  740. for(i = 0; i < samples; i+= chans) {
  741. for(j=0;j<chans;j++)
  742. buf[i+j] = (float)((double)buf[i+j] * a1);
  743. a1 += aincr;
  744. }
  745. }
  746. /*************************** CHECK_EXCISE_SPLICES ****************************/
  747. int check_excise_splices(dataptr dz)
  748. {
  749. int k;
  750. if(dz->lparray[CUT_STTSAMP][0] <= 0) {
  751. dz->iparam[CUT_NO_STT] = TRUE;
  752. dz->lparray[CUT_STTSPLI][0] = 0;
  753. } else {
  754. dz->iparam[CUT_NO_STT] = FALSE;
  755. if((dz->lparray[CUT_STTSPLI][0] = dz->lparray[CUT_STTSAMP][0] - dz->iparam[CUT_HLFSPLEN])<0) {
  756. sprintf(errstr,"initial excise is too close to start of file for splice\n");
  757. return(DATA_ERROR);
  758. }
  759. dz->lparray[CUT_STTSAMP][0] += dz->iparam[CUT_HLFSPLEN];
  760. }
  761. for(k=1;k<dz->iparam[EXCISE_CNT];k++) {
  762. dz->lparray[CUT_STTSPLI][k] = dz->lparray[CUT_STTSAMP][k] - dz->iparam[CUT_HLFSPLEN];
  763. dz->lparray[CUT_STTSAMP][k] += dz->iparam[CUT_HLFSPLEN];
  764. }
  765. for(k=0;k<dz->iparam[EXCISE_CNT];k++) {
  766. dz->lparray[CUT_ENDSPLI][k] = dz->lparray[CUT_ENDSAMP][k] + dz->iparam[CUT_HLFSPLEN];
  767. dz->lparray[CUT_ENDSAMP][k] -= dz->iparam[CUT_HLFSPLEN];
  768. if(dz->lparray[CUT_ENDSAMP][k] < dz->lparray[CUT_STTSAMP][k]) {
  769. sprintf(errstr,"Excised segment %d too short for splices (shorten splices?)\n",k+1);
  770. return(DATA_ERROR);
  771. }
  772. if(k && (dz->lparray[CUT_STTSPLI][k] < dz->lparray[CUT_ENDSPLI][k-1])) {
  773. sprintf(errstr,"Retained segment between excise %d & %d is too short for splices.\n",k,k+1);
  774. return(DATA_ERROR);
  775. }
  776. }
  777. if(dz->lparray[CUT_ENDSPLI][k-1] >= dz->insams[0]) {
  778. dz->iparam[CUT_NO_END] = TRUE;
  779. if(dz->iparam[CUT_NO_STT]==TRUE && dz->iparam[EXCISE_CNT]==1) {
  780. sprintf(errstr,"This process would remove the entire file!\n");
  781. return(DATA_ERROR);
  782. }
  783. if(dz->lparray[CUT_ENDSAMP][k-1] < dz->insams[0]) {
  784. fprintf(stdout,"INFO: End of final excise = END of FILE (it's closer than SPLICELEN).\n");
  785. fflush(stdout);
  786. }
  787. }
  788. return(FINISHED);
  789. }
  790. /**************************** DO_ZCUT ********************************/
  791. int do_zcut(dataptr dz)
  792. {
  793. int exit_status;
  794. int start_wr = 0, end_wr, last_end_wr, samps_to_wr, secs_to_wr ,extra, samps_written;
  795. int shsecsize = F_SECSIZE, last_total_samps;
  796. if(dz->process != MANY_ZCUTS)
  797. display_virtual_time(0L,dz);
  798. do {
  799. last_total_samps = dz->total_samps_read;
  800. if((exit_status = read_samps(dz->sampbuf[IBUF],dz))<0)
  801. return(exit_status);
  802. } while(dz->total_samps_read < dz->iparam[CUT_CUT]);
  803. if(dz->iparam[CUT_CUT]) {
  804. start_wr = dz->iparam[CUT_CUT] - last_total_samps;
  805. start_wr = find_zero(start_wr,dz->ssampsread,dz);
  806. }
  807. if(dz->iparam[CUT_END] <= dz->total_samps_read) {
  808. end_wr = dz->iparam[CUT_END] - last_total_samps;
  809. end_wr = find_zero(end_wr,dz->ssampsread,dz);
  810. if(end_wr - start_wr > 0) {
  811. if(dz->process == MANY_ZCUTS)
  812. exit_status = write_samps_no_report((dz->sampbuf[IBUF]+start_wr),(end_wr - start_wr),&samps_written,dz);
  813. else
  814. exit_status = write_samps((dz->sampbuf[IBUF]+start_wr),(end_wr - start_wr),dz);
  815. if(exit_status < 0)
  816. return(exit_status);
  817. }
  818. } else {
  819. samps_to_wr = dz->buflen - start_wr;
  820. secs_to_wr = samps_to_wr/shsecsize;
  821. extra = samps_to_wr - (secs_to_wr * shsecsize);
  822. samps_to_wr = secs_to_wr * shsecsize;
  823. if(samps_to_wr > 0) {
  824. if(dz->process == MANY_ZCUTS)
  825. exit_status = write_samps_no_report((dz->sampbuf[IBUF]+start_wr),samps_to_wr,&samps_written,dz);
  826. else
  827. exit_status = write_samps((dz->sampbuf[IBUF]+start_wr),samps_to_wr,dz);
  828. if(exit_status < 0)
  829. return(exit_status);
  830. }
  831. end_wr = dz->buflen - extra;
  832. memcpy((char *)(dz->sampbuf[OBUF] - extra),(char *)(dz->sampbuf[OBUF] + end_wr),extra*sizeof(float));
  833. dz->sampbuf[OBUF] -= extra;
  834. for(;;) {
  835. last_total_samps = dz->total_samps_read;
  836. if((exit_status = read_samps(dz->sampbuf[IBUF],dz))<0)
  837. return(exit_status);
  838. if(dz->total_samps_read < dz->iparam[CUT_END]) {
  839. if(dz->process == MANY_ZCUTS)
  840. exit_status = write_samps_no_report(dz->sampbuf[OBUF],dz->buflen,&samps_written,dz);
  841. else
  842. exit_status = write_samps(dz->sampbuf[OBUF],dz->buflen,dz);
  843. if(exit_status < 0)
  844. return(exit_status);
  845. memcpy((char *)dz->sampbuf[OBUF],(char *)(dz->sampbuf[OBUF] + end_wr),extra*sizeof(float));
  846. } else {
  847. last_end_wr = dz->iparam[CUT_END] - last_total_samps;
  848. if(!dz->iparam[CUT_GOES_TO_END]) {
  849. last_end_wr = find_zero(last_end_wr+extra,dz->ssampsread+extra,dz);
  850. if(last_end_wr > 0) {
  851. if(dz->process == MANY_ZCUTS)
  852. exit_status = write_samps_no_report(dz->sampbuf[OBUF],last_end_wr,&samps_written,dz);
  853. else
  854. exit_status = write_samps(dz->sampbuf[OBUF],last_end_wr,dz);
  855. if(exit_status < 0)
  856. return(exit_status);
  857. }
  858. } else {
  859. if(last_end_wr + extra > 0) {
  860. if(dz->process == MANY_ZCUTS)
  861. exit_status = write_samps_no_report(dz->sampbuf[OBUF],(last_end_wr + extra),&samps_written,dz);
  862. else
  863. exit_status = write_samps(dz->sampbuf[OBUF],(last_end_wr + extra),dz);
  864. if(exit_status < 0)
  865. return(exit_status);
  866. }
  867. }
  868. break;
  869. }
  870. }
  871. }
  872. return(FINISHED);
  873. }
  874. /************************ FIND_ZERO **************************/
  875. int find_zero(int end,int allsamps,dataptr dz)
  876. {
  877. int n = end;
  878. int m = end;
  879. int phase, in_nloop = 0, in_mloop = 0;
  880. if(smpflteq(dz->sampbuf[OBUF][n],0.0))
  881. return(end);
  882. if(dz->sampbuf[OBUF][n]>0.0)
  883. phase = 1;
  884. else
  885. phase = -1;
  886. switch(phase) {
  887. case(1):
  888. while(n>0) {
  889. in_nloop = 1;
  890. if(dz->sampbuf[OBUF][n]<0.0) {
  891. n++;
  892. break;
  893. }
  894. n--;
  895. }
  896. if(n==0 && in_nloop)
  897. n = dz->buflen; /* FLAG NO ZERO FOUND BACKWRD */
  898. while(m<allsamps) {
  899. in_mloop = 1;
  900. if(dz->sampbuf[OBUF][m]<0.0)
  901. break;
  902. m++;
  903. }
  904. if(m==allsamps && in_mloop)
  905. m = dz->buflen; /* FLAG NO ZERO FOUND FORWRD */
  906. break;
  907. case(-1):
  908. while(n>0) {
  909. in_nloop = 1;
  910. if(dz->sampbuf[OBUF][n]>0.0) {
  911. n++;
  912. break;
  913. }
  914. n--;
  915. }
  916. if(n==0 && in_nloop)
  917. n = dz->buflen;
  918. while(m<allsamps) {
  919. in_mloop = 1;
  920. if(dz->sampbuf[OBUF][m]>0.0)
  921. break;
  922. m++;
  923. }
  924. if(m==allsamps && in_mloop)
  925. m = dz->buflen;
  926. break;
  927. }
  928. if(m==dz->buflen && n==dz->buflen) /* NO ZERO CROSSING FOUND */
  929. return(allsamps);
  930. if((m-end) < (end-n)) /* ELSE RETURN CLOSEST ZERO CROSSING */
  931. return(m);
  932. return(n);
  933. }
  934. /****************************** DO_EXCISE *************************/
  935. int do_excise(dataptr dz)
  936. {
  937. int exit_status;
  938. int k;
  939. int last_total_samps;
  940. int obufleft, ibufleft;
  941. dz->total_samps_read = 0;
  942. display_virtual_time(0L,dz);
  943. last_total_samps = dz->total_samps_read;
  944. if((exit_status = read_samps(dz->sampbuf[IBUF],dz))<0)
  945. return(exit_status);
  946. obufleft = dz->buflen;
  947. ibufleft = dz->buflen;
  948. if((exit_status = copy_excise_chunk(&last_total_samps,&obufleft,&ibufleft,0,dz))<0)
  949. return(exit_status);
  950. obufleft = dz->buflen - (dz->lparray[CUT_STTSPLI][0] - last_total_samps);
  951. ibufleft = dz->buflen - (dz->lparray[CUT_STTSPLI][0] - last_total_samps);
  952. exit_status = CONTINUE;
  953. for(k=0;k<dz->iparam[EXCISE_CNT];k++) {
  954. if(k==0) {
  955. if(!dz->iparam[CUT_NO_STT]) {
  956. if((exit_status = do_excise_beginning(&last_total_samps,&obufleft,0,dz))<0)
  957. return(exit_status);
  958. }
  959. } else {
  960. if((exit_status = do_excise_beginning(&last_total_samps,&obufleft,k,dz))<0)
  961. return(exit_status);
  962. }
  963. if(k==dz->iparam[EXCISE_CNT]-1 && dz->iparam[CUT_NO_END])
  964. exit_status = FINISHED;
  965. if(exit_status==FINISHED)
  966. break;
  967. if((exit_status = do_excise_ending(&last_total_samps,&obufleft,&ibufleft,k,dz))<0)
  968. return(exit_status);
  969. }
  970. if(exit_status==FINISHED)
  971. return do_excise_finish(obufleft,dz);
  972. return write_excise_end(last_total_samps,obufleft,ibufleft,dz);
  973. }
  974. /*************************** DO_EXCISE_FINISH ***********************/
  975. int do_excise_finish(int obufleft,dataptr dz)
  976. {
  977. int exit_status;
  978. int overflow;
  979. dz->sbufptr[SPLBUF] = dz->sampbuf[SPLBUF];
  980. if((overflow = dz->iparam[CUT_SPLEN] - obufleft)<=0) {
  981. memcpy((char *)dz->sbufptr[OBUF],(char *)dz->sbufptr[SPLBUF],dz->iparam[CUT_SPLEN]*sizeof(float));
  982. dz->sbufptr[OBUF] += dz->iparam[CUT_SPLEN];
  983. if(dz->sbufptr[OBUF]-dz->sampbuf[OBUF] > 0) {
  984. if((exit_status = write_samps(dz->sampbuf[OBUF],(dz->sbufptr[OBUF]-dz->sampbuf[OBUF]),dz))<0)
  985. return(exit_status);
  986. }
  987. } else {
  988. memcpy((char *)dz->sbufptr[OBUF],(char *)dz->sbufptr[SPLBUF],obufleft*sizeof(float));
  989. if((exit_status = write_samps(dz->sampbuf[OBUF],dz->buflen,dz))<0)
  990. return(exit_status);
  991. dz->sbufptr[SPLBUF] += obufleft;
  992. if(overflow > 0) {
  993. if((exit_status = write_samps(dz->sbufptr[SPLBUF],overflow,dz))<0)
  994. return(exit_status);
  995. }
  996. }
  997. return(FINISHED);
  998. }
  999. /**************************** CROSSPLICE ******************************/
  1000. void crossplice(dataptr dz)
  1001. {
  1002. double a1, aincr;
  1003. int chans = dz->infile->channels;
  1004. int sampgrps = dz->iparam[CUT_SPLEN]/chans;
  1005. float *splptr2 = dz->sampbuf[SPLBUF2];
  1006. float *splptr = dz->sampbuf[SPLBUF];
  1007. int i;
  1008. int j;
  1009. aincr = 1.0/sampgrps;
  1010. a1 = aincr;
  1011. for(i = 0; i < dz->iparam[CUT_SPLEN]; i+= chans) {
  1012. for(j=0;j<chans;j++) {
  1013. *splptr2 = (float)((double)(*splptr2) * a1);
  1014. *splptr++ += *splptr2++;
  1015. }
  1016. a1 += aincr;
  1017. }
  1018. }
  1019. /*********************************** DO_EXCISE_BEGINNING *************************/
  1020. int do_excise_beginning(int *last_total_samps,int *obufleft,int k,dataptr dz)
  1021. {
  1022. int exit_status = CONTINUE;
  1023. int overflow, remnant, startsplice_in_buf, startsamp_in_buf, samps_to_copy;
  1024. dz->sbufptr[SPLBUF] = dz->sampbuf[SPLBUF];
  1025. startsplice_in_buf = dz->lparray[CUT_STTSPLI][k] - *last_total_samps;
  1026. dz->sbufptr[IBUF] = dz->sampbuf[IBUF] + startsplice_in_buf;
  1027. *obufleft = dz->sampbuf[SPLBUF] - dz->sbufptr[OBUF];
  1028. startsamp_in_buf = dz->lparray[CUT_STTSAMP][k] - *last_total_samps;
  1029. if((overflow = startsamp_in_buf - dz->buflen)<=0) {
  1030. memcpy((char *)dz->sbufptr[SPLBUF],(char *)dz->sbufptr[IBUF],
  1031. dz->iparam[CUT_SPLEN] * sizeof(float));
  1032. dz->sbufptr[IBUF] += dz->iparam[CUT_SPLEN];
  1033. if(dz->sbufptr[IBUF] >= dz->sampbuf[OBUF]) {
  1034. if(dz->samps_left<=0)
  1035. exit_status = FINISHED;
  1036. else {
  1037. *last_total_samps = dz->total_samps_read;
  1038. if((exit_status = read_samps(dz->sampbuf[IBUF],dz))<0)
  1039. return(exit_status);
  1040. dz->sbufptr[IBUF] = dz->sampbuf[IBUF];
  1041. exit_status = CONTINUE;
  1042. }
  1043. }
  1044. } else {
  1045. remnant = dz->iparam[CUT_SPLEN]-overflow;
  1046. memcpy((char *)dz->sbufptr[SPLBUF],(char *)dz->sbufptr[IBUF],remnant*sizeof(float));
  1047. dz->sbufptr[SPLBUF] += remnant;
  1048. while(overflow > 0) {
  1049. *last_total_samps = dz->total_samps_read;
  1050. if((exit_status = read_samps(dz->sampbuf[IBUF],dz))<0)
  1051. return(exit_status);
  1052. dz->sbufptr[IBUF] = dz->sampbuf[IBUF];
  1053. samps_to_copy = min(overflow,dz->buflen);
  1054. overflow -= samps_to_copy;
  1055. memcpy((char *)dz->sbufptr[SPLBUF],(char *)dz->sbufptr[IBUF],samps_to_copy*sizeof(float));
  1056. dz->sbufptr[IBUF] += samps_to_copy;
  1057. dz->sbufptr[SPLBUF] += samps_to_copy;
  1058. startsamp_in_buf = dz->lparray[CUT_STTSAMP][k] - *last_total_samps;
  1059. }
  1060. exit_status = CONTINUE;
  1061. }
  1062. dosplice(dz->sampbuf[SPLBUF],dz->iparam[CUT_SPLEN],dz->infile->channels,DOWNSLOPE);
  1063. dz->sbufptr[SPLBUF] = dz->sampbuf[SPLBUF];
  1064. return(exit_status);
  1065. }
  1066. /****************************** DO_EXCISE_ENDING ****************************/
  1067. int do_excise_ending(int *last_total_samps,int *obufleft,int *ibufleft,int k,dataptr dz)
  1068. {
  1069. int exit_status;
  1070. int overflow, remnant;
  1071. int endsplice_in_buf, endsamp_in_buf;
  1072. int samps_to_copy;
  1073. dz->sbufptr[SPLBUF2] = dz->sampbuf[SPLBUF2];
  1074. while(dz->total_samps_read < dz->lparray[CUT_ENDSAMP][k]) {
  1075. *last_total_samps = dz->total_samps_read;
  1076. if((exit_status = read_samps(dz->sampbuf[IBUF],dz))<0)
  1077. return(exit_status);
  1078. }
  1079. endsamp_in_buf = dz->lparray[CUT_ENDSAMP][k] - *last_total_samps;
  1080. endsplice_in_buf = dz->lparray[CUT_ENDSPLI][k] - *last_total_samps;
  1081. dz->sbufptr[IBUF] = dz->sampbuf[IBUF] + endsamp_in_buf;
  1082. if((overflow = endsplice_in_buf - dz->buflen)<=0) {
  1083. memcpy((char *)dz->sbufptr[SPLBUF2],(char *)dz->sbufptr[IBUF],
  1084. dz->iparam[CUT_SPLEN] * sizeof(float));
  1085. dz->sbufptr[IBUF] += dz->iparam[CUT_SPLEN];
  1086. if(dz->sbufptr[IBUF] >= dz->sampbuf[OBUF]) {
  1087. if(dz->samps_left<=0)
  1088. return(FINISHED);
  1089. else {
  1090. *last_total_samps = dz->total_samps_read;
  1091. if((exit_status = read_samps(dz->sampbuf[IBUF],dz))<0)
  1092. return(exit_status);
  1093. dz->sbufptr[IBUF] = dz->sampbuf[IBUF];
  1094. }
  1095. }
  1096. } else {
  1097. remnant = dz->iparam[CUT_SPLEN]-overflow;
  1098. memcpy((char *)dz->sbufptr[SPLBUF2],(char *)dz->sbufptr[IBUF],remnant*sizeof(float));
  1099. dz->sbufptr[SPLBUF2] += remnant;
  1100. while(overflow > 0) {
  1101. *last_total_samps = dz->total_samps_read;
  1102. if((exit_status = read_samps(dz->sampbuf[IBUF],dz))<0)
  1103. return(exit_status);
  1104. dz->sbufptr[IBUF] = dz->sampbuf[IBUF];
  1105. samps_to_copy = min(overflow,dz->buflen);
  1106. overflow -= samps_to_copy;
  1107. memcpy((char *)dz->sbufptr[SPLBUF2],(char *)dz->sbufptr[IBUF],samps_to_copy*sizeof(float));
  1108. dz->sbufptr[IBUF] += overflow;
  1109. dz->sbufptr[SPLBUF2] += samps_to_copy;
  1110. }
  1111. }
  1112. crossplice(dz);
  1113. dz->sbufptr[SPLBUF] = dz->sampbuf[SPLBUF];
  1114. dz->sbufptr[SPLBUF2] = dz->sampbuf[SPLBUF2];
  1115. if((overflow = dz->iparam[CUT_SPLEN] - *obufleft)<=0) {
  1116. memcpy((char *)dz->sbufptr[OBUF],(char *)dz->sbufptr[SPLBUF],
  1117. dz->iparam[CUT_SPLEN] * sizeof(float));
  1118. dz->sbufptr[OBUF] += dz->iparam[CUT_SPLEN];
  1119. } else {
  1120. memcpy((char *)dz->sbufptr[OBUF],(char *)dz->sbufptr[SPLBUF],(*obufleft)*sizeof(float));
  1121. dz->sbufptr[SPLBUF] += *obufleft;
  1122. while(overflow > 0) {
  1123. if((exit_status = write_samps(dz->sampbuf[OBUF],dz->buflen,dz))<0)
  1124. return(exit_status);
  1125. dz->sbufptr[OBUF] = dz->sampbuf[OBUF];
  1126. samps_to_copy = min(overflow,dz->buflen);
  1127. overflow -= samps_to_copy;
  1128. memcpy((char *)dz->sbufptr[OBUF],(char *)dz->sbufptr[SPLBUF],samps_to_copy*sizeof(float));
  1129. // MAY 2010
  1130. // dz->sbufptr[OBUF] += overflow;
  1131. dz->sbufptr[OBUF] += samps_to_copy;
  1132. dz->sbufptr[SPLBUF] += samps_to_copy;
  1133. }
  1134. }
  1135. *obufleft = dz->sampbuf[SPLBUF] - dz->sbufptr[OBUF];
  1136. *ibufleft = dz->ssampsread - (dz->sbufptr[IBUF] - dz->sampbuf[IBUF]);
  1137. if(k < dz->iparam[EXCISE_CNT]-1)
  1138. copy_excise_chunk(last_total_samps,obufleft,ibufleft,k+1,dz);
  1139. return(CONTINUE);
  1140. }
  1141. /************************* WRITE_EXCISE_END *****************************/
  1142. int write_excise_end(int last_total_samps,int obufleft,int ibufleft,dataptr dz)
  1143. {
  1144. int exit_status;
  1145. int finished = 0, do_it = 0;
  1146. while(!finished) {
  1147. if (obufleft == ibufleft) do_it = 0;
  1148. else if(obufleft > ibufleft) do_it = 1;
  1149. else if(obufleft < ibufleft) do_it = 2;
  1150. switch(do_it) {
  1151. case(0): /* EQUAL SPACE IN INPUT & OUTPUT BUFFERS */
  1152. memcpy((char *)dz->sbufptr[OBUF],(char *)dz->sbufptr[IBUF],ibufleft * sizeof(float));
  1153. dz->sbufptr[OBUF] += ibufleft;
  1154. if(dz->sbufptr[OBUF] - dz->sampbuf[OBUF] > 0) {
  1155. if((exit_status =
  1156. write_samps(dz->sampbuf[OBUF],(dz->sbufptr[OBUF] - dz->sampbuf[OBUF]),dz))<0)
  1157. return(exit_status);
  1158. }
  1159. while(dz->samps_left) {
  1160. last_total_samps = dz->total_samps_read;
  1161. if((exit_status = read_samps(dz->sampbuf[IBUF],dz))<0)
  1162. return(exit_status);
  1163. if(dz->ssampsread > 0) {
  1164. if((exit_status = write_samps(dz->sampbuf[IBUF],dz->ssampsread,dz))<0)
  1165. return(exit_status);
  1166. }
  1167. }
  1168. finished = 1;
  1169. break;
  1170. case(1): /* MORE SPACE IN OUTPUT BUFFER */
  1171. memcpy((char *)dz->sbufptr[OBUF],(char *)dz->sbufptr[IBUF],ibufleft * sizeof(float));
  1172. dz->sbufptr[OBUF] += ibufleft;
  1173. obufleft -= ibufleft;
  1174. if(dz->samps_left<=0) {
  1175. if(dz->sbufptr[OBUF]-dz->sampbuf[OBUF] > 0) {
  1176. if((exit_status =
  1177. write_samps(dz->sampbuf[OBUF],(dz->sbufptr[OBUF]-dz->sampbuf[OBUF]),dz))<0)
  1178. return(exit_status);
  1179. }
  1180. finished = 1;
  1181. break;
  1182. }
  1183. last_total_samps = dz->total_samps_read;
  1184. if((exit_status = read_samps(dz->sampbuf[IBUF],dz))<0)
  1185. return(exit_status);
  1186. dz->sbufptr[IBUF] = dz->sampbuf[IBUF];
  1187. ibufleft = dz->ssampsread;
  1188. break;
  1189. case(2): /* MORE SPACE IN INPUT BUFFER */
  1190. memcpy((char *)dz->sbufptr[OBUF],(char *)dz->sbufptr[IBUF],obufleft * sizeof(float));
  1191. dz->sbufptr[IBUF] += obufleft;
  1192. ibufleft -= obufleft;
  1193. if((exit_status = write_samps(dz->sampbuf[OBUF],dz->buflen,dz))<0)
  1194. return(exit_status);
  1195. dz->sbufptr[OBUF] = dz->sampbuf[OBUF];
  1196. obufleft = dz->buflen;
  1197. break;
  1198. }
  1199. }
  1200. return(FINISHED);
  1201. }
  1202. /************************* COPY_EXCISE_CHUNK *************************/
  1203. int copy_excise_chunk(int *last_total_samps,int *obufleft,int *ibufleft,int k,dataptr dz)
  1204. {
  1205. int exit_status;
  1206. int samps_to_copy = dz->lparray[CUT_STTSPLI][k] - (*last_total_samps + (dz->sbufptr[IBUF] - dz->sampbuf[IBUF]));
  1207. while(samps_to_copy>0) {
  1208. if((*obufleft > *ibufleft) && (samps_to_copy >= *ibufleft)) {
  1209. memcpy((char *)dz->sbufptr[OBUF],(char *)dz->sbufptr[IBUF],(*ibufleft)*sizeof(float));
  1210. samps_to_copy -= *ibufleft;
  1211. *obufleft -= *ibufleft;
  1212. dz->sbufptr[OBUF] += *ibufleft;
  1213. *last_total_samps = dz->total_samps_read;
  1214. if((exit_status = read_samps(dz->sampbuf[IBUF],dz))<0)
  1215. return(exit_status);
  1216. dz->sbufptr[IBUF] = dz->sampbuf[IBUF];
  1217. *ibufleft = dz->buflen;
  1218. } else if((*ibufleft >= *obufleft) && (samps_to_copy >= *obufleft)) {
  1219. memcpy((char *)dz->sbufptr[OBUF],(char *)dz->sbufptr[IBUF],(*obufleft)*sizeof(float));
  1220. if((exit_status = write_samps(dz->sampbuf[OBUF],dz->buflen,dz))<0)
  1221. return(exit_status);
  1222. samps_to_copy -= *obufleft;
  1223. *ibufleft -= *obufleft;
  1224. dz->sbufptr[IBUF] += *obufleft;
  1225. dz->sbufptr[OBUF] = dz->sampbuf[OBUF];
  1226. *obufleft = dz->buflen;
  1227. } else {
  1228. memcpy((char *)dz->sbufptr[OBUF],(char *)dz->sbufptr[IBUF],samps_to_copy*sizeof(float));
  1229. dz->sbufptr[OBUF] += samps_to_copy;
  1230. *obufleft -= samps_to_copy;
  1231. dz->sbufptr[IBUF] += samps_to_copy;
  1232. *ibufleft -= samps_to_copy;
  1233. samps_to_copy = 0;
  1234. }
  1235. }
  1236. return(FINISHED);
  1237. }
  1238. /******************************** DO_INSERT **********************************/
  1239. int do_insert(dataptr dz)
  1240. {
  1241. int exit_status;
  1242. int seektest;
  1243. float *cp; /* current buffer pointer */
  1244. int ref, ssampsread; /* reference value for insert loop */
  1245. int first = TRUE; /* first is first read flag */
  1246. int buffxs2, samps_to_read, sects_to_read, samps_read,n, m, samps_in_buf, remainder, outsize = 0;
  1247. // TW 2010
  1248. int /* secs_to_write, */ samps_to_move, seek_samps = 0, seek_sects, samps_to_write;
  1249. int c;
  1250. short shsecsize = F_SECSIZE;
  1251. dz->total_samps_written = 0;
  1252. if(algo2) {
  1253. while(dz->total_samps_written < dz->tempsize) {
  1254. memset((char *)dz->bigbuf,0,dz->buflen * sizeof(float));
  1255. if(dz->total_samps_read < dz->insams[0]) {
  1256. if((exit_status = read_samps(dz->bigbuf,dz))<0)
  1257. return(exit_status);
  1258. }
  1259. if((samps_to_write = min(dz->buflen,dz->tempsize - dz->total_samps_written)) > 0) {
  1260. if((exit_status = write_samps(dz->bigbuf,samps_to_write,dz))<0)
  1261. return(exit_status);
  1262. }
  1263. }
  1264. return(FINISHED);
  1265. }
  1266. ref = dz->buflen - F_SECSIZE;
  1267. /* READ FIRST PART OF INFILE, AND GET SPLICE SECTION */
  1268. fprintf(stdout,"INFO: Reading first file\n");
  1269. fflush(stdout);
  1270. for(c = 1; c <= dz->iparam[CUT_BUFCNT]; c++) { /* ANY WHOLE BUFFERS COPIED */
  1271. if((samps_read = fgetfbufEx(dz->sampbuf[0], dz->buflen,dz->ifd[0],0))!=dz->buflen) {
  1272. sprintf(errstr,"Bad sound read 7.\n");
  1273. if(samps_read<0)
  1274. return(SYSTEM_ERROR);
  1275. return(PROGRAM_ERROR);
  1276. }
  1277. // if((samps_written = fputfbufEx(dz->sampbuf[0], dz->buflen,dz->ofd))!=samps_read) {
  1278. if((exit_status = write_samps(dz->sampbuf[0],dz->buflen,dz))< 0)
  1279. return(exit_status);
  1280. }
  1281. if(dz->iparam[CUT_SECCNT]) { /* SPARE SECTORS BEFORE SPLICE */
  1282. samps_to_read = dz->iparam[CUT_SECCNT] * F_SECSIZE;
  1283. if((samps_read = fgetfbufEx(dz->sampbuf[0],samps_to_read,dz->ifd[0],0))!=samps_to_read) {
  1284. sprintf(errstr,"Bad sound read 8.\n");
  1285. if(samps_read<0)
  1286. return(SYSTEM_ERROR);
  1287. return(PROGRAM_ERROR);
  1288. }
  1289. if(samps_read > 0) {
  1290. if((exit_status = write_samps(dz->sampbuf[0],samps_read,dz)) < 0)
  1291. return(exit_status);
  1292. }
  1293. }
  1294. if((samps_read = fgetfbufEx(dz->sampbuf[0], dz->iparam[CUT_SECSREMAIN] * F_SECSIZE,dz->ifd[0],0))<=0) {
  1295. if(samps_read<0) {
  1296. sprintf(errstr,"Bad sound read 9.\n");
  1297. return(SYSTEM_ERROR);
  1298. } else if(dz->iparam[CUT_SECSREMAIN] > 0) {
  1299. sprintf(errstr,"Bad sound read 9.\n");
  1300. return(PROGRAM_ERROR);
  1301. }
  1302. }
  1303. samps_to_move = (dz->iparam[CUT_SECSREMAIN] * F_SECSIZE) - dz->iparam[CUT_BUFXS];
  1304. if(samps_to_move<0) {
  1305. sprintf(errstr,"Arithmetic problem 1\n");
  1306. return(PROGRAM_ERROR);
  1307. }
  1308. if(samps_to_move) {
  1309. memcpy((char *)dz->sampbuf[SPLBUF],(char *)(dz->sampbuf[0] + dz->iparam[CUT_BUFXS]),
  1310. samps_to_move * sizeof(float));
  1311. if(!dz->vflag[INSERT_OVERWRITE])
  1312. memcpy((char *)dz->sampbuf[SAVEBUF],(char *)dz->sampbuf[SPLBUF],
  1313. samps_to_move * sizeof(float));
  1314. }
  1315. if(dz->iparam[CUT_SPLEN] > 0) {
  1316. dosplice(dz->sampbuf[SPLBUF], dz->iparam[CUT_SPLEN], dz->infile->channels, DOWNSLOPE);
  1317. if(!dz->vflag[INSERT_OVERWRITE])
  1318. dosplice(dz->sampbuf[SAVEBUF], dz->iparam[CUT_SPLEN], dz->infile->channels, UPSLOPE);
  1319. }
  1320. cp = dz->sampbuf[0] + dz->iparam[CUT_BUFXS];
  1321. memset((char *)cp,0,(dz->buflen - dz->iparam[CUT_BUFXS]) * sizeof(float));
  1322. if((dz->process == EDIT_INSERT2) || dz->vflag[INSERT_OVERWRITE]) {
  1323. switch(dz->process) {
  1324. case(EDIT_INSERT2):
  1325. seek_samps = dz->iparam[CUT_END] - (2 * dz->iparam[CUT_SPLEN]);
  1326. break;
  1327. case(EDIT_INSERT):
  1328. seek_samps = dz->iparam[CUT_CUT] + dz->insams[1]
  1329. - (2 * dz->iparam[CUT_SPLEN]);
  1330. break;
  1331. case(EDIT_INSERTSIL):
  1332. if(silent_end)
  1333. seek_samps = dz->iparam[CUT_CUT] - dz->iparam[CUT_SPLEN];
  1334. else
  1335. seek_samps = dz->iparam[CUT_CUT]
  1336. + dz->iparam[CUT_LEN] - (2 * dz->iparam[CUT_SPLEN]);
  1337. break;
  1338. }
  1339. seek_sects = seek_samps / F_SECSIZE;
  1340. if((seektest = sndseekEx(dz->ifd[0],seek_sects * F_SECSIZE,0))!=seek_sects * F_SECSIZE) {
  1341. if(seektest<0) {
  1342. sprintf(errstr,"Seek failed.\n");
  1343. return(SYSTEM_ERROR);
  1344. } else {
  1345. sprintf(errstr,"Seek problem 1 in insert().\n");
  1346. return(PROGRAM_ERROR);
  1347. }
  1348. }
  1349. buffxs2 = (seek_samps - (seek_sects * F_SECSIZE));
  1350. samps_to_read = dz->iparam[CUT_SPLEN] + buffxs2 + F_SECSIZE;
  1351. if(((sects_to_read = samps_to_read/F_SECSIZE) * F_SECSIZE)!= samps_to_read)
  1352. sects_to_read++;
  1353. samps_to_read = sects_to_read * F_SECSIZE;
  1354. if((samps_read = fgetfbufEx(dz->sampbuf[SAVEBUF],samps_to_read,dz->ifd[0],0))<=0) {
  1355. sprintf(errstr,"Bad sound read 10.\n");
  1356. if(samps_read<0)
  1357. return(SYSTEM_ERROR);
  1358. return(PROGRAM_ERROR);
  1359. }
  1360. ssampsread = samps_read;
  1361. if(buffxs2) {
  1362. for(n=0,m = buffxs2;n<ssampsread - buffxs2;n++,m++)
  1363. dz->sampbuf[SAVEBUF][n] = dz->sampbuf[SAVEBUF][m];
  1364. }
  1365. dz->iparam[CUT_BUFREMNANT] = ssampsread - (buffxs2 + dz->iparam[CUT_SPLEN]);
  1366. dosplice(dz->sampbuf[SAVEBUF], dz->iparam[CUT_SPLEN], dz->infile->channels, UPSLOPE);
  1367. }
  1368. switch(dz->process) {
  1369. case(EDIT_INSERT):
  1370. case(EDIT_INSERT2):
  1371. fprintf(stdout,"INFO: Inserting file.\n");
  1372. break;
  1373. case(EDIT_INSERTSIL):
  1374. fprintf(stdout,"INFO: Inserting silence\n");
  1375. break;
  1376. }
  1377. fflush(stdout);
  1378. for(c = 1; c <= dz->iparam[CUT_BUFCNT2]; c++) { /* ANY WHOLE BUFFERS COPIED */
  1379. switch(dz->process) {
  1380. case(EDIT_INSERT):
  1381. case(EDIT_INSERT2):
  1382. if((samps_read = fgetfbufEx(cp, dz->iparam[SMALLBUFSIZ],dz->ifd[1],0))!=dz->iparam[SMALLBUFSIZ]) {
  1383. sprintf(errstr,"Bad sound read 11.\n");
  1384. if(samps_read<0)
  1385. return(SYSTEM_ERROR);
  1386. return(PROGRAM_ERROR);
  1387. }
  1388. if(!flteq(dz->param[INSERT_LEVEL],1.0)) {
  1389. if((exit_status = gain_insert_buffer(cp,dz->iparam[SMALLBUFSIZ],dz->param[INSERT_LEVEL]))<0)
  1390. return(exit_status);
  1391. }
  1392. break;
  1393. case(EDIT_INSERTSIL):
  1394. memset((char *)cp,0, dz->iparam[SMALLBUFSIZ] * sizeof(float));
  1395. break;
  1396. }
  1397. if(first) {
  1398. first = FALSE;
  1399. if(dz->iparam[CUT_SPLEN] > 0) {/* splice beginning of input */
  1400. if(dz->process==EDIT_INSERT)
  1401. dosplice(cp, dz->iparam[CUT_SPLEN], dz->infile->channels, UPSLOPE);
  1402. for(n=0;n<dz->iparam[CUT_SPLEN];n++)
  1403. cp[n] += dz->sampbuf[SPLBUF][n]; /* creates cross-splice */
  1404. }
  1405. }
  1406. if(dz->iparam[SMALLBUFSIZ] > 0) {
  1407. if((exit_status = write_samps(dz->sampbuf[0],dz->iparam[SMALLBUFSIZ],dz)) < 0)
  1408. return(exit_status);
  1409. }
  1410. if(dz->iparam[CUT_BUFXS]) {
  1411. cp = dz->sampbuf[0] + ref;
  1412. movmem((char *)cp, (char *)dz->sampbuf[0], dz->iparam[CUT_BUFXS] * sizeof(float));
  1413. cp = dz->sampbuf[0] + dz->iparam[CUT_BUFXS];
  1414. }
  1415. }
  1416. if(dz->iparam[CUT_SECCNT2]) { /* SPARE SECTORS BEFORE END SPLICE */
  1417. switch(dz->process) {
  1418. case(EDIT_INSERT):
  1419. case(EDIT_INSERT2):
  1420. if((samps_read =
  1421. fgetfbufEx(cp, dz->iparam[CUT_SECCNT2] * F_SECSIZE,dz->ifd[1],0))!=dz->iparam[CUT_SECCNT2] * F_SECSIZE) {
  1422. sprintf(errstr,"Bad sound read 12.\n");
  1423. if(samps_read<0)
  1424. return(SYSTEM_ERROR);
  1425. return(PROGRAM_ERROR);
  1426. }
  1427. if(!flteq(dz->param[INSERT_LEVEL],1.0)) {
  1428. if((exit_status = gain_insert_buffer(cp,dz->iparam[CUT_SECCNT2] * F_SECSIZE,dz->param[INSERT_LEVEL]))<0)
  1429. return(exit_status);
  1430. }
  1431. break;
  1432. case(EDIT_INSERTSIL):
  1433. memset((char *)cp,0, (dz->iparam[CUT_SECCNT2] * F_SECSIZE) * sizeof(float));
  1434. break;
  1435. }
  1436. if(first) {
  1437. first = FALSE;
  1438. if(dz->iparam[CUT_SPLEN] > 0) {/* splice beginning of input */
  1439. if(dz->process==EDIT_INSERT)
  1440. dosplice(cp, dz->iparam[CUT_SPLEN], dz->infile->channels, UPSLOPE);
  1441. for(n=0;n<dz->iparam[CUT_SPLEN];n++)
  1442. cp[n] += dz->sampbuf[SPLBUF][n];
  1443. }
  1444. }
  1445. if(dz->iparam[CUT_SECCNT2] > 0) {
  1446. if((exit_status = write_samps(dz->sampbuf[0],dz->iparam[CUT_SECCNT2] * F_SECSIZE,dz)) < 0)
  1447. return(exit_status);
  1448. }
  1449. if(dz->iparam[CUT_BUFXS]) {
  1450. cp = dz->sampbuf[0] + (dz->iparam[CUT_SECCNT2] * shsecsize);
  1451. movmem((char *)cp, (char *)dz->sampbuf[0],
  1452. dz->iparam[CUT_BUFXS] * sizeof(float));
  1453. cp = dz->sampbuf[0] + dz->iparam[CUT_BUFXS];
  1454. }
  1455. }
  1456. switch(dz->process) {
  1457. case(EDIT_INSERT):
  1458. case(EDIT_INSERT2):
  1459. if((samps_read =
  1460. fgetfbufEx(cp, dz->iparam[CUT_SECSREMAIN2] * F_SECSIZE,dz->ifd[1],0))<=0) {
  1461. sprintf(errstr,"Bad sound read 13.\n");
  1462. if(samps_read<0)
  1463. return(SYSTEM_ERROR);
  1464. return(PROGRAM_ERROR);
  1465. }
  1466. if(!flteq(dz->param[INSERT_LEVEL],1.0)) {
  1467. if((exit_status = gain_insert_buffer(cp,dz->iparam[CUT_SECSREMAIN2] * F_SECSIZE,dz->param[INSERT_LEVEL]))<0)
  1468. return(exit_status);
  1469. }
  1470. break;
  1471. case(EDIT_INSERTSIL):
  1472. memset((char *)cp,0,(dz->iparam[CUT_SECSREMAIN2] * F_SECSIZE) * sizeof(float));
  1473. break;
  1474. }
  1475. if(first) { /* NO SECTORS BEFORE END SPLICE STARTS */
  1476. if(dz->iparam[CUT_SPLEN]>0) { /* splice beginning of file */
  1477. if(dz->process==EDIT_INSERT || dz->process==EDIT_INSERT2)
  1478. dosplice(cp, dz->iparam[CUT_SPLEN], dz->infile->channels, UPSLOPE);
  1479. for(n=0;n<dz->iparam[CUT_SPLEN];n++)
  1480. cp[n] += dz->sampbuf[SPLBUF][n];
  1481. }
  1482. }
  1483. cp = dz->sampbuf[0] + dz->iparam[CUT_BUFXS] + dz->iparam[CUT_SMPSREMAIN];
  1484. if(dz->iparam[CUT_SPLEN]>0) {
  1485. cp -= dz->iparam[CUT_SPLEN];
  1486. if(dz->process==EDIT_INSERT || dz->process==EDIT_INSERT2)
  1487. dosplice(cp, dz->iparam[CUT_SPLEN], dz->infile->channels, DOWNSLOPE);
  1488. if(!silent_end) {
  1489. for(n=0;n<dz->iparam[CUT_SPLEN];n++)
  1490. cp[n] += dz->sampbuf[SAVEBUF][n];
  1491. }
  1492. cp += dz->iparam[CUT_SPLEN];
  1493. }
  1494. for(n=0,m=dz->iparam[CUT_SPLEN];n<dz->iparam[CUT_BUFREMNANT];n++,m++) {
  1495. if(silent_end)
  1496. // cp[n] = (short)0;
  1497. cp[n] = (float)0;
  1498. else
  1499. cp[n] = dz->sampbuf[SAVEBUF][m];
  1500. }
  1501. cp += dz->iparam[CUT_BUFREMNANT];
  1502. samps_in_buf = cp - dz->sampbuf[0];
  1503. dz->iparam[CUT_SECCNT] = samps_in_buf/shsecsize;
  1504. dz->iparam[CUT_BUFXS] = samps_in_buf - (dz->iparam[CUT_SECCNT] * shsecsize);
  1505. if(dz->iparam[CUT_SECCNT] > 0) {
  1506. if((exit_status = write_samps(dz->sampbuf[0],dz->iparam[CUT_SECCNT] * F_SECSIZE,dz)) < 0)
  1507. return(exit_status);
  1508. }
  1509. cp = dz->sampbuf[0] + (dz->iparam[CUT_SECCNT] * shsecsize);
  1510. movmem((char *)cp, (char *)dz->sampbuf[0],
  1511. dz->iparam[CUT_BUFXS] * sizeof(float));
  1512. cp = dz->sampbuf[0] + dz->iparam[CUT_BUFXS];
  1513. remainder = dz->iparam[CUT_BUFXS];
  1514. fprintf(stdout,"INFO: Reading remainder of infile.\n");
  1515. fflush(stdout);
  1516. while((samps_read = fgetfbufEx(cp, dz->iparam[SMALLBUFSIZ],dz->ifd[0],0)) > 0) {
  1517. samps_to_write = min(dz->iparam[SMALLBUFSIZ],samps_read + dz->iparam[CUT_BUFXS]);
  1518. remainder = samps_read - ((dz->iparam[SMALLBUFSIZ]) - dz->iparam[CUT_BUFXS]);
  1519. if(silent_end)
  1520. memset((char *)dz->sampbuf[0],0,dz->buflen * sizeof(float));
  1521. if(samps_to_write > 0) {
  1522. if((exit_status = write_samps(dz->sampbuf[0],samps_to_write,dz)) < 0)
  1523. return(exit_status);
  1524. }
  1525. if(remainder > 0) {
  1526. cp = dz->sampbuf[0] + ref;
  1527. movmem((char *)cp, (char *)dz->sampbuf[0], remainder * sizeof(float));
  1528. cp = dz->sampbuf[0] + dz->iparam[CUT_BUFXS];
  1529. }
  1530. }
  1531. if(samps_read<0) {
  1532. sprintf(errstr,"Bad sound read.\n");
  1533. return(SYSTEM_ERROR);
  1534. }
  1535. if(remainder > 0) {
  1536. if((exit_status = write_samps(dz->sampbuf[0],remainder,dz))<=0)
  1537. return(exit_status);
  1538. }
  1539. if (dz->process == EDIT_INSERT2)
  1540. outsize = dz->insams[0] + dz->insams[1] - dz->iparam[CUT_SPLEN];
  1541. else if(dz->vflag[INSERT_OVERWRITE])
  1542. outsize = dz->insams[0];
  1543. else {
  1544. switch(dz->process) {
  1545. case(EDIT_INSERT):
  1546. outsize = dz->insams[0] + dz->insams[1] - dz->iparam[CUT_SPLEN];
  1547. break;
  1548. case(EDIT_INSERTSIL):
  1549. outsize = dz->insams[0] + dz->iparam[CUT_LEN]
  1550. - dz->iparam[CUT_SPLEN];
  1551. break;
  1552. }
  1553. }
  1554. dz->total_samps_written = outsize; /* for truncation calculations */
  1555. return(FINISHED);
  1556. }
  1557. /******************************** GAIN_INSERT_BUFFER ********************************/
  1558. int gain_insert_buffer(float *thisbuf,int size,double gain)
  1559. {
  1560. int n;
  1561. double d;
  1562. if(gain > 1.0) {
  1563. for(n=0;n < size; n++) {
  1564. if(fabs(d = (double)thisbuf[n] * gain) > (double)F_MAXSAMP) {
  1565. sprintf(errstr,"gain has caused insertfile to distort.\n");
  1566. return(DATA_ERROR);
  1567. }
  1568. thisbuf[n] = (float) /*round*/(d);
  1569. }
  1570. } else {
  1571. for(n=0;n < size; n++)
  1572. thisbuf[n] = (float) /*round*/((double)thisbuf[n] * gain);
  1573. }
  1574. return(FINISHED);
  1575. }
  1576. /******************************** SETUP_EXCISE_OUTDISPLAY_LEN ********************************/
  1577. void setup_excise_outdisplay_len(dataptr dz)
  1578. {
  1579. int n;
  1580. dz->tempsize = dz->insams[0];
  1581. for(n=0;n<dz->iparam[EXCISE_CNT]-1;n++)
  1582. dz->tempsize -= dz->lparray[CUT_ENDSAMP][n] - dz->lparray[CUT_STTSAMP][n];
  1583. if(dz->iparam[CUT_NO_END])
  1584. dz->tempsize -= dz->insams[0] - dz->lparray[CUT_STTSAMP][n];
  1585. else
  1586. dz->tempsize -= dz->lparray[CUT_ENDSAMP][n] - dz->lparray[CUT_STTSAMP][n];
  1587. if(dz->tempsize<=0)
  1588. dz->tempsize = 1; /* trap later divides by zero !! */
  1589. }
  1590. /************************** JOIN_PCONSISTENCY ***************************/
  1591. int join_pconsistency(dataptr dz)
  1592. {
  1593. int n, m;
  1594. int stsplen;
  1595. double *p, *q;
  1596. double sr = (double)dz->infile->srate;
  1597. int chans = dz->infile->channels;
  1598. stsplen = round(dz->param[CUT_SPLEN] * MS_TO_SECS * sr);
  1599. dz->iparam[CUT_SPLEN] = stsplen * chans;
  1600. if((dz->parray[SPLICE_UP] = (double *)malloc(stsplen * sizeof(double)))==NULL) {
  1601. sprintf(errstr,"INSUFFICENT MEMORY for first splice table.\n");
  1602. return(MEMORY_ERROR);
  1603. }
  1604. if((dz->parray[SPLICE_DN] = (double *)malloc(stsplen * sizeof(double)))==NULL) {
  1605. sprintf(errstr,"INSUFFICENT MEMORY for 2nd splice table.\n");
  1606. return(MEMORY_ERROR);
  1607. }
  1608. p = dz->parray[SPLICE_UP];
  1609. q = dz->parray[SPLICE_DN];
  1610. for(n=0;n<stsplen;n++) {
  1611. *p++ = (double)n/(double)stsplen;
  1612. *q++ = (double)(stsplen-n)/(double)stsplen;
  1613. }
  1614. if(dz->insams[0] < 2 * dz->iparam[CUT_SPLEN]) {
  1615. sprintf(errstr,"File 1 too short for specified spliclength.\n");
  1616. return(DATA_ERROR);
  1617. }
  1618. dz->tempsize = dz->insams[0];
  1619. switch(dz->process) {
  1620. case(EDIT_JOIN):
  1621. dz->tempsize = dz->insams[0];
  1622. for(n=1;n<dz->infilecnt;n++) {
  1623. if(dz->insams[n] < 2 * dz->iparam[CUT_SPLEN]) {
  1624. sprintf(errstr,"File %d too short for specified spliclength.\n",n+1);
  1625. return(DATA_ERROR);
  1626. }
  1627. dz->tempsize += dz->insams[n] - dz->iparam[CUT_SPLEN];
  1628. }
  1629. break;
  1630. case(JOIN_SEQDYN):
  1631. dz->tempsize = 0;
  1632. for(n=0;n<dz->itemcnt;n++) {
  1633. m = dz->iparray[0][n];
  1634. if(dz->insams[m] < 2 * dz->iparam[CUT_SPLEN]) {
  1635. sprintf(errstr,"File %d too short for specified splicelength.\n",m+1);
  1636. return(DATA_ERROR);
  1637. }
  1638. dz->tempsize += dz->insams[m] - dz->iparam[CUT_SPLEN];
  1639. }
  1640. break;
  1641. case(JOIN_SEQ):
  1642. dz->tempsize = 0;
  1643. for(n=0;n<dz->itemcnt;n++) {
  1644. if(n >= dz->iparam[MAX_LEN])
  1645. break;
  1646. m = dz->iparray[0][n];
  1647. if(dz->insams[m] < 2 * dz->iparam[CUT_SPLEN]) {
  1648. sprintf(errstr,"File %d too short for specified splicelength.\n",m+1);
  1649. return(DATA_ERROR);
  1650. }
  1651. dz->tempsize += dz->insams[m] - dz->iparam[CUT_SPLEN];
  1652. }
  1653. break;
  1654. }
  1655. return(FINISHED);
  1656. }
  1657. /************************** CREATE_JOIN_BUFFER ***************************/
  1658. int create_join_buffer(dataptr dz)
  1659. {
  1660. int seccnt;
  1661. size_t bigbufsize;
  1662. int framesize = F_SECSIZE * dz->infile->channels;
  1663. int fl_secsize = F_SECSIZE * sizeof(float);
  1664. int splicelen = dz->iparam[CUT_SPLEN] * dz->infile->channels;
  1665. bigbufsize = (size_t) Malloc(-1);
  1666. bigbufsize = (bigbufsize/fl_secsize) * fl_secsize;
  1667. bigbufsize -= fl_secsize;
  1668. dz->buflen = (int)(bigbufsize/sizeof(float));
  1669. dz->buflen = (dz->buflen/framesize) * framesize;
  1670. if(dz->buflen <= 0)
  1671. dz->buflen = framesize;
  1672. if(splicelen > dz->buflen - F_SECSIZE) {
  1673. dz->buflen = splicelen;
  1674. if(((seccnt = dz->buflen/framesize) * framesize) < dz->buflen)
  1675. seccnt++;
  1676. dz->buflen = seccnt * framesize;
  1677. }
  1678. if(dz->buflen<=0
  1679. || (dz->bigbuf = (float *)malloc(sizeof(float) * (dz->buflen + F_SECSIZE
  1680. + splicelen)))==NULL) {
  1681. sprintf(errstr, "INSUFFICIENT MEMORY for sounds.\n");
  1682. return(MEMORY_ERROR);
  1683. }
  1684. dz->sampbuf[BBUF] = dz->bigbuf;
  1685. dz->sampbuf[BUFEND] = dz->sampbuf[BBUF] + dz->buflen;
  1686. dz->sampbuf[SPLICEBUF] = dz->sampbuf[BUFEND] + F_SECSIZE;
  1687. return(FINISHED);
  1688. }
  1689. /************************** CREATE_JOIN_SEQ_BUFFER ***************************/
  1690. int create_join_seq_buffer(dataptr dz)
  1691. {
  1692. int seccnt, OK = 0;
  1693. int last_buflen = 0;
  1694. int framesize = F_SECSIZE * dz->infile->channels;
  1695. int fl_secsize = F_SECSIZE * sizeof(float);
  1696. size_t bigbufsize = (size_t) Malloc(-1);
  1697. bigbufsize = (bigbufsize/fl_secsize) * fl_secsize;
  1698. bigbufsize -= fl_secsize; /* Leave F_SECSIZE available for malloc */
  1699. dz->buflen = (int)(bigbufsize/sizeof(float));
  1700. dz->buflen = (dz->buflen/framesize) * framesize;
  1701. if(dz->buflen <= 0)
  1702. dz->buflen = framesize;
  1703. while(!OK) {
  1704. if(dz->buflen <= last_buflen) {
  1705. sprintf(errstr, "Too many channels to cope with.\n");
  1706. return(MEMORY_ERROR);
  1707. }
  1708. if(dz->buflen<=0
  1709. || (dz->bigbuf = (float *)malloc(sizeof(float) * ((dz->buflen * 2) + F_SECSIZE
  1710. + dz->iparam[CUT_SPLEN])))==NULL) {
  1711. sprintf(errstr, "INSUFFICIENT MEMORY for sounds.\n");
  1712. return(MEMORY_ERROR);
  1713. }
  1714. last_buflen = dz->buflen;
  1715. dz->sampbuf[COPYBUF] = dz->bigbuf;
  1716. dz->bigbuf += dz->buflen;
  1717. dz->sampbuf[BBUF] = dz->bigbuf;
  1718. dz->sampbuf[BUFEND] = dz->sampbuf[BBUF] + dz->buflen;
  1719. dz->sampbuf[SPLICEBUF] = dz->sampbuf[BUFEND] + F_SECSIZE;
  1720. if(dz->iparam[CUT_SPLEN] <= dz->buflen - F_SECSIZE) /* splice must fit in buffer */
  1721. OK = 1;
  1722. else {
  1723. dz->buflen = dz->iparam[CUT_SPLEN];
  1724. if(((seccnt = dz->buflen/framesize) * framesize) < dz->buflen)
  1725. seccnt++;
  1726. dz->buflen = seccnt * framesize;
  1727. }
  1728. }
  1729. return(FINISHED);
  1730. }
  1731. /*************************** DO_JOINING *****************************
  1732. *
  1733. * (A) Sets special loop condition for zero splice length, see (B).
  1734. * (0) For every input file.
  1735. * (1) Set 'samps_to_get' to equal size of file MINUS number of samps
  1736. * we will use in end-of0-file splice.
  1737. * (2) Set the total_fsamps_read to zero..
  1738. * (3) and the number of reads OF THIS FILE to zero.
  1739. * (4) NORMAL CASE lmt = 0.
  1740. Read the file. Note the number of samps read. Add this to the total
  1741. * number of samps read from this file.
  1742. * If the TOTAL number of samps read, EXCEEDS 'samps_to_get' then we
  1743. * have read some samps in the END SPLICE REGION. The number of those
  1744. * samps is 'overspill'.
  1745. * If we have not read any samps in END SPLICE REGION...
  1746. * (i.e. we cannot be at the end of the file, and hence we must have
  1747. * read a FULL BUFFER!!!).
  1748. * (B) ZERO SPLICE LENGTH CASE, LMT = -1.
  1749. * In this case, an overspill of zero just tells us that the
  1750. * entire block has been read .. no special adjustments need
  1751. * to be made for splice overlaps, so we can drop out of
  1752. * the while loop when we get ZERO overspill in this case.
  1753. * (5) If this is the first read of this file, then the START-SPLICE must
  1754. * be in the buffer. So do the start-splice IN SITU.
  1755. * (6) As the END_SPLICE is not in the buffer, and the buffer is full,
  1756. * we can WRITE the whole existing buffer to the output.
  1757. * (7) Increment the count of reads OF THIS FILE.
  1758. * (8) If we have left the read_loop for the current file, with readcnt
  1759. * remaining at zero, the start of the current file must be in the
  1760. * current buffer.
  1761. * We can therefore do the start_splice IN SITU in the current buffer.
  1762. * (9) Housekeep1
  1763. * (a) finds the address of the start of end_splice
  1764. * (b) copies whatever part of the splice is in the buffer, into
  1765. * the splice buffer.
  1766. * (10) If not all of the splice is in this buffer (splice_remnant>0)...
  1767. * (a) Reads rest of splice directly to splice buffer
  1768. * (b) finds the size and address of any part-sector existing
  1769. * just prior to the splice-area.
  1770. * (c) Writes the whole buufer up to start of this part-sector..
  1771. * (d) copies part_sector to start of buffer
  1772. * (e) resets readbuf address and size of readbuffer.
  1773. * (11) Otherwise, reset the read-place in buffer, and the (remaining) size
  1774. * of the read_buffer.
  1775. * (12) On leaving loop, do any splice required at end of file.
  1776. * (13) Flush buffer.
  1777. */
  1778. int do_joining(dataptr dz)
  1779. {
  1780. int exit_status;
  1781. int total_fsamps_read, samps_to_get, samps_read, samps_to_write;
  1782. int n, readcnt, lmt = 0;
  1783. int overspill, splice_remnant;
  1784. dz->iparam[CUT_SMPSREMAIN] = dz->buflen;
  1785. dz->sampbuf[READBUF] = dz->sampbuf[BBUF];
  1786. if(dz->iparam[CUT_SPLEN]==0)
  1787. lmt = -1; /* A */
  1788. for(n=0;n<dz->infilecnt;n++) { /* 0 */
  1789. fprintf(stdout,"INFO: Processing FILE %d\n",n+1);
  1790. fflush(stdout);
  1791. if((samps_to_get = dz->insams[n] - dz->iparam[CUT_SPLEN])<=0) {
  1792. sprintf(errstr,"File %d is too short for the given splicelength\n",n+1);
  1793. return(GOAL_FAILED);
  1794. }
  1795. /* 1 */
  1796. total_fsamps_read = 0; /* 2 */
  1797. readcnt = 0; /* 3 */
  1798. for(;;) {
  1799. if((samps_read = fgetfbufEx(dz->sampbuf[READBUF],
  1800. dz->iparam[CUT_SMPSREMAIN],dz->ifd[n],0))<0) {
  1801. sprintf(errstr, "Can't read from input soundfile\n");
  1802. return(SYSTEM_ERROR);
  1803. }
  1804. overspill = (total_fsamps_read += samps_read) - samps_to_get;
  1805. if(overspill > lmt)
  1806. break;
  1807. if(dz->iparam[CUT_SPLEN]>0 && readcnt==0) /* B */
  1808. do_join_startsplice(n,dz); /* 5 */
  1809. if((exit_status = write_exact_samps(dz->sampbuf[BBUF],dz->buflen,dz))<0)
  1810. return(exit_status); /* 6 */
  1811. housekeep2(samps_read,dz);
  1812. readcnt++; /* 7 */
  1813. }
  1814. if(dz->iparam[CUT_SPLEN]>0) {
  1815. if(readcnt==0) /* 8 */
  1816. do_join_startsplice(n,dz);
  1817. housekeep1(samps_read,overspill,dz); /* 9 */
  1818. if((splice_remnant = dz->iparam[CUT_SPLEN] - overspill)>0) { /* 10 */
  1819. if((exit_status = do_join_write(n,splice_remnant,(int)(overspill),dz))<0)
  1820. return(exit_status);
  1821. } else {
  1822. if((exit_status = reset_join_buffer_params(dz))<0) /* 11 */
  1823. return(exit_status);
  1824. }
  1825. } else {
  1826. dz->sbufptr[ENDSPLICE_ADDR] = dz->sampbuf[READBUF] + samps_read;
  1827. if((exit_status = reset_join_buffer_params(dz))<0)
  1828. return(exit_status);
  1829. }
  1830. if(sndcloseEx(dz->ifd[n]) < 0) {
  1831. fprintf(stdout, "WARNING: Can't close input soundfile %d\n",n+1);
  1832. fflush(stdout);
  1833. }
  1834. dz->ifd[n] = -1;
  1835. }
  1836. if(dz->iparam[CUT_SPLEN]>0) {
  1837. if(dz->vflag[SPLICE_END]) /* 12 */
  1838. do_join_endsplice(dz);
  1839. memcpy((char *)dz->sampbuf[READBUF],(char *)dz->sampbuf[SPLICEBUF],
  1840. dz->iparam[CUT_SPLEN] * sizeof(float));
  1841. }
  1842. if((samps_to_write = dz->sampbuf[READBUF] + dz->iparam[CUT_SPLEN] - dz->sampbuf[BBUF])>0)
  1843. return write_samps(dz->sampbuf[BBUF],samps_to_write,dz); /* 13 */
  1844. return FINISHED;
  1845. }
  1846. /************************ READ_JOIN_SPLICE_REMNANT ********************************
  1847. *
  1848. * Reads any EXTRA bit of the splice NOT captured in main buffer.
  1849. */
  1850. int read_join_splice_remnant(int n,int splice_remnant,int oversamps,dataptr dz)
  1851. {
  1852. int toread = splice_remnant/F_SECSIZE, samps_read;
  1853. if((toread * F_SECSIZE) != splice_remnant)
  1854. toread += 1;
  1855. toread *= F_SECSIZE;
  1856. /* MUST ASK FOR WHOLE NO OF SECTORS : AND THIS MUST BE >= NO OF SAMPS WANTED */
  1857. if((samps_read = fgetfbufEx(dz->sampbuf[SPLICEBUF] + oversamps,toread,dz->ifd[n],0))<0) {
  1858. sprintf(errstr,"Can't read samples for splice from input soundfile.\n");
  1859. return(SYSTEM_ERROR);
  1860. }
  1861. if(samps_read != splice_remnant) {
  1862. sprintf(errstr,"Problem reading part splice-buffer.\n");
  1863. return(PROGRAM_ERROR);
  1864. }
  1865. return(FINISHED);
  1866. }
  1867. /********************************* DO_JOIN_STARTSPLICE ************************/
  1868. void do_join_startsplice(int k,dataptr dz)
  1869. {
  1870. int n;
  1871. int m;
  1872. float *a = dz->sampbuf[READBUF];
  1873. float *b = dz->sampbuf[SPLICEBUF];
  1874. int chans = dz->infile->channels;
  1875. double *p = dz->parray[SPLICE_UP];
  1876. double *q = dz->parray[SPLICE_DN];
  1877. a = dz->sampbuf[READBUF];
  1878. if(k==0)
  1879. do_join_initial_splice(chans,dz);
  1880. else {
  1881. for(n=0;n<dz->iparam[CUT_SPLEN];n+=chans) {
  1882. for(m=0;m<chans;m++) {
  1883. *a= (float) /*round*/((*q * (double)(*b)) + (*p * (double)(*a)));
  1884. a++;
  1885. b++;
  1886. }
  1887. p++;
  1888. q++;
  1889. }
  1890. }
  1891. }
  1892. /************************** DO_JOIN_INITIAL_SPLICE ********************************/
  1893. void do_join_initial_splice(int chans,dataptr dz)
  1894. {
  1895. int n;
  1896. int m;
  1897. float *a = dz->sampbuf[BBUF];
  1898. double *p = dz->parray[SPLICE_UP];
  1899. if(dz->vflag[SPLICE_START]) {
  1900. for(n=0;n<dz->iparam[CUT_SPLEN];n+=chans) {
  1901. for(m=0;m<chans;m++) {
  1902. *a = (float) /*round*/(*p * (double)(*a));
  1903. a++;
  1904. }
  1905. p++;
  1906. }
  1907. }
  1908. }
  1909. /*********************************** DO_JOIN_ENDSPLICE **************************
  1910. *
  1911. * Put a fade on data in splice_buffer.
  1912. */
  1913. void do_join_endsplice(dataptr dz)
  1914. {
  1915. int n;
  1916. int m, chans = dz->infile->channels;
  1917. float *b = dz->sampbuf[SPLICEBUF];
  1918. double *q = dz->parray[SPLICE_DN];
  1919. for(n=0;n<dz->iparam[CUT_SPLEN];n+=chans) {
  1920. for(m=0;m<chans;m++) {
  1921. *b = (float) /*round*/(*q * (double)(*b));
  1922. b++;
  1923. }
  1924. q++;
  1925. }
  1926. }
  1927. /************************* HOUSEKEEP1 *******************************
  1928. *
  1929. * (1) 'body' is the number of samps of the current file, in the
  1930. * current buffer, NOT COUNTING the splice portion.
  1931. * (2) ENDSPLICE_ADDR, is offset from the address where we
  1932. * last read into this buffer, by 'body'.
  1933. * (3) Copy whatever part of the end-splice region is in this buffer
  1934. * into the splice-buffer.
  1935. */
  1936. void housekeep1(int samps_read,int overspill,dataptr dz)
  1937. {
  1938. int body = (samps_read - overspill); /* 1 */
  1939. dz->sbufptr[ENDSPLICE_ADDR] = dz->sampbuf[READBUF] + body; /* 2 */
  1940. memcpy((char *)dz->sampbuf[SPLICEBUF],(char *)dz->sbufptr[ENDSPLICE_ADDR],overspill * sizeof(float)); /* 3 */
  1941. }
  1942. /************************* HOUSEKEEP2 *******************************
  1943. *
  1944. * (1) Find end of final write into this buffer.
  1945. * (2) Find size of part-sector written beyond ACTUAL (read) buffer.
  1946. * (3) Copy part-sector to start of ACTUAL buffer.
  1947. * (4) Reset start of readbuf to end of this part-sector.
  1948. * (5) Set size of readbuffer to full-size (we have an extra sector for
  1949. * overrun at end!!).
  1950. */
  1951. void housekeep2(int samps_read,dataptr dz)
  1952. {
  1953. float *write_end = dz->sampbuf[READBUF] + samps_read; /* 1 */
  1954. int part_sector_size = write_end - dz->sampbuf[BUFEND]; /* 2 */
  1955. memcpy((char *)dz->sampbuf[BBUF],(char *)dz->sampbuf[BUFEND],part_sector_size * sizeof(float)); /* 3 */
  1956. dz->sampbuf[READBUF] = dz->sampbuf[BBUF] + part_sector_size; /* 4 */
  1957. dz->iparam[CUT_SMPSREMAIN] = dz->buflen; /* 5 */
  1958. }
  1959. /******************************* DO_JOIN_WRITE **********************************
  1960. *
  1961. * (1) Read the unread PART of the splice directly into the end of the
  1962. * splice_buffer.
  1963. * (2) The distance of the start of this end-splice from the start of
  1964. * the ACTUAL buffer is given by (ENDSPLICE_ADDR - buffer).
  1965. * (3) This distance in SECTORS (truncated).
  1966. * (4) This truncated distance in samps.
  1967. * (5) The size of any part_sector preceding the splice-start.
  1968. * (6) The address of this part_sector.
  1969. * (7) Write the existing buffer, up as far as the last complete sector
  1970. * before the splice sector begins.
  1971. * (8) Copy any incomplete sector (prior to the splice) to the start
  1972. * of the buffer.
  1973. * (9) Set the reading-in point (readbuf) to the end of that part_sector.
  1974. * (10) Set the space remaining in the buffer (dz->iparam[CUT_SAMPREMAIN]) to the
  1975. * total buffersize (bear in mind that there is a guard SECSIZE
  1976. * of address space at the end, to allow for the part_sectors
  1977. * inserted at the start of the buffer).
  1978. */
  1979. int do_join_write(int n,int splice_remnant,int oversamps,dataptr dz)
  1980. {
  1981. int exit_status;
  1982. int shsecsize = F_SECSIZE;
  1983. int samps_from_buf_start,secdist,sector_sampdist,part_sector_size;
  1984. float *part_sector_addr;
  1985. if((exit_status = read_join_splice_remnant(n,splice_remnant,oversamps,dz))<0)
  1986. return(exit_status); /* 1 */
  1987. samps_from_buf_start = dz->sbufptr[ENDSPLICE_ADDR] - dz->sampbuf[BBUF]; /* 2 */
  1988. secdist = samps_from_buf_start/shsecsize; /* 3 */
  1989. sector_sampdist = secdist * shsecsize; /* 4 */
  1990. part_sector_size = (samps_from_buf_start - sector_sampdist); /* 5 */
  1991. part_sector_addr = dz->sampbuf[BBUF] + sector_sampdist; /* 6 */
  1992. if(sector_sampdist) {
  1993. if((exit_status = write_samps(dz->sampbuf[BBUF],sector_sampdist,dz))<0)
  1994. return(exit_status); /* 7 */
  1995. }
  1996. if(part_sector_size && (dz->sampbuf[BBUF]!=part_sector_addr)) /* 8 */
  1997. memcpy((char *)dz->sampbuf[BBUF],(char *)part_sector_addr,part_sector_size * sizeof(float));
  1998. dz->sampbuf[READBUF] = dz->sampbuf[BBUF] + (part_sector_size); /* 9 */
  1999. // SEPT 2010
  2000. dz->iparam[CUT_SMPSREMAIN] = dz->buflen; /* 10 */
  2001. return(FINISHED);
  2002. }
  2003. /*********************** RESET_JOIN_BUFFER_PARAMS ****************************
  2004. *
  2005. * (1) Set the next read-in address to be at the START of the
  2006. * current file's end-splice area. Note that the end-splice
  2007. * samps have been saved to the splice-buffer. The start-splice
  2008. * samps of the new file will be written over the end-splice values
  2009. * and the splice then created IN SITU.
  2010. * (2) Check how many complete sectors remain in the ACTUAL buffer.
  2011. * (3) Convert this to a sampcount.
  2012. * (4) Unless there was an exact number of sectors, add one extra sector
  2013. * of samps. This ensures that the reads will write to the end of OR
  2014. * beyond the end of the ACTUAL buffer, so that WRITES will be
  2015. * valid. This is safe because we have allowed an extra sector
  2016. * at the end of the buffer.
  2017. */
  2018. int reset_join_buffer_params(dataptr dz)
  2019. {
  2020. int shsecsize = F_SECSIZE;
  2021. int bufcheck;
  2022. dz->sampbuf[READBUF] = dz->sbufptr[ENDSPLICE_ADDR]; /* 1 */
  2023. if((bufcheck = dz->sampbuf[BUFEND] - dz->sbufptr[ENDSPLICE_ADDR])==0) { /* 2 */
  2024. dz->iparam[CUT_SMPSREMAIN] = dz->buflen;
  2025. dz->sbufptr[ENDSPLICE_ADDR] = dz->sampbuf[BBUF];
  2026. dz->sampbuf[READBUF] = dz->sampbuf[BBUF];
  2027. } else {
  2028. dz->iparam[CUT_SMPSREMAIN] = bufcheck/shsecsize;
  2029. dz->iparam[CUT_SMPSREMAIN] *= F_SECSIZE; /* 3 */
  2030. if(bufcheck != dz->iparam[CUT_SMPSREMAIN])
  2031. dz->iparam[CUT_SMPSREMAIN] += F_SECSIZE; /* 4 */
  2032. if(dz->iparam[CUT_SMPSREMAIN] < F_SECSIZE) { /* 5 */
  2033. sprintf(errstr,"Zero buffer sectorsize: impossible!?: reset_join_buffer_params()\n");
  2034. return(PROGRAM_ERROR);
  2035. }
  2036. }
  2037. return(FINISHED);
  2038. }
  2039. /******************************** DO_INSERTSIL_MANY **********************************/
  2040. int do_insertsil_many(dataptr dz)
  2041. {
  2042. int exit_status;
  2043. int last_total_samps_read, endsamp, startsamp, inbuf_location;
  2044. int chans = dz->infile->channels;
  2045. int here = 0;
  2046. int here_in_splice = 0;
  2047. int in_downsplice = 0;
  2048. int in_upsplice = 0;
  2049. int in_zero = 0;
  2050. int splicelen = dz->iparam[CUT_SPLEN];
  2051. dz->total_samps_read = 0;
  2052. while(dz->total_samps_read < dz->insams[0]) {
  2053. last_total_samps_read = dz->total_samps_read;
  2054. if((exit_status = read_samps(dz->bigbuf,dz))<0)
  2055. return(exit_status);
  2056. if (here >= dz->iparam[EXCISE_CNT]) {
  2057. if(dz->ssampsread > 0) {
  2058. if((exit_status = write_samps(dz->bigbuf,dz->ssampsread,dz))<0)
  2059. return(exit_status); /* 7 */
  2060. }
  2061. continue;
  2062. }
  2063. if (in_downsplice) {
  2064. endsamp = dz->lparray[CUT_STTSAMP][here] - last_total_samps_read;
  2065. if(endsamp <= dz->buflen) {
  2066. do_other_splice(dz->bigbuf,splicelen,here_in_splice,splicelen,chans,1);
  2067. in_downsplice = 0;
  2068. here_in_splice = 0;
  2069. } else {
  2070. do_other_splice(dz->bigbuf,splicelen,here_in_splice,here_in_splice + dz->buflen,chans,1);
  2071. here_in_splice += dz->buflen;
  2072. if(dz->ssampsread > 0) {
  2073. if((exit_status = write_samps(dz->bigbuf,dz->ssampsread,dz))<0)
  2074. return(exit_status); /* 7 */
  2075. }
  2076. continue;
  2077. }
  2078. } else if (in_zero) {
  2079. endsamp = dz->lparray[CUT_ENDSAMP][here] - last_total_samps_read;
  2080. if(endsamp <= dz->buflen) {
  2081. memset((char *)dz->bigbuf,0,endsamp * sizeof(float));
  2082. in_zero = 0;
  2083. } else {
  2084. memset((char *)dz->bigbuf,0,dz->buflen * sizeof(float));
  2085. if(dz->ssampsread > 0) {
  2086. if((exit_status = write_samps(dz->bigbuf,dz->ssampsread,dz))<0)
  2087. return(exit_status); /* 7 */
  2088. }
  2089. continue;
  2090. }
  2091. } else if (in_upsplice) {
  2092. endsamp = dz->lparray[CUT_ENDSPLI][here] - last_total_samps_read;
  2093. if(endsamp <= dz->buflen) {
  2094. do_other_splice(dz->bigbuf,splicelen,here_in_splice,splicelen,chans,0);
  2095. in_upsplice = 0;
  2096. here_in_splice = 0;
  2097. here++; /* To next set of values */
  2098. } else {
  2099. do_other_splice(dz->bigbuf,splicelen,here_in_splice,here_in_splice + dz->buflen,chans,0);
  2100. here_in_splice += dz->buflen;
  2101. if(dz->ssampsread > 0) {
  2102. if((exit_status = write_samps(dz->bigbuf,dz->ssampsread,dz))<0)
  2103. return(exit_status); /* 7 */
  2104. }
  2105. continue;
  2106. }
  2107. }
  2108. while(here < dz->iparam[EXCISE_CNT]) {
  2109. if(dz->lparray[CUT_STTSPLI][here] >= dz->total_samps_read) {
  2110. break;
  2111. }
  2112. inbuf_location = dz->lparray[CUT_STTSPLI][here] - last_total_samps_read;
  2113. if(inbuf_location >= 0 && inbuf_location < dz->ssampsread) {
  2114. startsamp = dz->lparray[CUT_STTSPLI][here] % dz->buflen;
  2115. if(dz->lparray[CUT_STTSAMP][here] < dz->total_samps_read) {
  2116. endsamp = dz->lparray[CUT_STTSAMP][here] % dz->buflen;
  2117. do_other_splice((dz->bigbuf + startsamp),splicelen,0,splicelen,chans,1);
  2118. here_in_splice = 0;
  2119. in_downsplice = 0;
  2120. } else {
  2121. endsamp = dz->buflen;
  2122. here_in_splice = endsamp - startsamp;
  2123. do_other_splice((dz->bigbuf + startsamp),splicelen,0,here_in_splice,chans,1);
  2124. in_downsplice = 1;
  2125. break;
  2126. }
  2127. }
  2128. inbuf_location = dz->lparray[CUT_STTSAMP][here] - last_total_samps_read;
  2129. if(inbuf_location >= 0 && inbuf_location < dz->ssampsread) {
  2130. startsamp = dz->lparray[CUT_STTSAMP][here] % dz->buflen;
  2131. if(dz->lparray[CUT_ENDSAMP][here] < dz->total_samps_read) {
  2132. endsamp = dz->lparray[CUT_ENDSAMP][here] % dz->buflen;
  2133. memset((char *)(dz->bigbuf + startsamp),0,(endsamp - startsamp) * sizeof(float));
  2134. in_zero = 0;
  2135. } else {
  2136. endsamp = dz->buflen;
  2137. memset((char *)(dz->bigbuf + startsamp),0,(endsamp - startsamp) * sizeof(float));
  2138. in_zero = 1;
  2139. break;
  2140. }
  2141. }
  2142. inbuf_location = dz->lparray[CUT_ENDSAMP][here] - last_total_samps_read;
  2143. if(inbuf_location >= 0 && inbuf_location < dz->ssampsread) {
  2144. startsamp = dz->lparray[CUT_ENDSAMP][here] % dz->buflen;
  2145. if(dz->lparray[CUT_ENDSPLI][here] < dz->total_samps_read) {
  2146. endsamp = dz->lparray[CUT_ENDSPLI][here] % dz->buflen;
  2147. do_other_splice((dz->bigbuf + startsamp),splicelen,0,splicelen,chans,0);
  2148. here_in_splice = 0;
  2149. in_upsplice = 0;
  2150. } else {
  2151. endsamp = dz->buflen;
  2152. here_in_splice = endsamp - startsamp;
  2153. do_other_splice((dz->bigbuf + startsamp),splicelen,0,here_in_splice,chans,0);
  2154. in_upsplice = 1;
  2155. break;
  2156. }
  2157. }
  2158. here++;
  2159. }
  2160. if(dz->ssampsread > 0) {
  2161. if((exit_status = write_samps(dz->bigbuf,dz->ssampsread,dz))<0)
  2162. return(exit_status); /* 7 */
  2163. }
  2164. }
  2165. return(FINISHED);
  2166. }
  2167. void do_other_splice(float *buf, int splicelen, int start_in_splice, int end_in_splice, int chans, int invert)
  2168. {
  2169. double a1 = 0.0, aincr;
  2170. register int i, j, k;
  2171. int sampgrps = splicelen/chans;
  2172. aincr = 1.0/sampgrps;
  2173. if(invert) {
  2174. aincr = -aincr;
  2175. a1 = 1.0 + aincr;
  2176. }
  2177. a1 += (aincr * start_in_splice);
  2178. for(i = 0, k = start_in_splice; k < end_in_splice; i+= chans, k += chans) {
  2179. for(j=0;j<chans;j++)
  2180. buf[i+j] = (float)((double)buf[i+j] * a1);
  2181. a1 += aincr;
  2182. }
  2183. }
  2184. /**************************** DO_RANDCUTS ****************************/
  2185. int do_randcuts(dataptr dz)
  2186. {
  2187. // int bigbufsize;
  2188. int exit_status, namelen, cutendno;
  2189. float *obuf;
  2190. char *outfilename;
  2191. int rel_bufend, rel_bufstart, abs_bufend, abs_bufstart, /*origbufsize*/origbuflen;
  2192. int rel_cutend, last_cut, next_cut, cutlen;
  2193. int chans = dz->infile->channels;
  2194. int stereo_splicelen = SHRED_SPLICELEN * chans;
  2195. int part_splice, splice_start, samps_to_write;
  2196. if((exit_status = get_lengths(stereo_splicelen,dz))<0)
  2197. return(PROGRAM_ERROR);
  2198. namelen = strlen(dz->wordstor[0]);
  2199. if(sloom)
  2200. namelen--; /* Drop the 0 at end of name */
  2201. //FEB 2010 TW
  2202. if((outfilename = (char *)malloc((namelen + 6 + 10) * sizeof(char)))==NULL) {
  2203. sprintf(errstr,"INSUFFICIENT MEMORY for outfilename.\n");
  2204. return(MEMORY_ERROR);
  2205. }
  2206. strcpy(outfilename,dz->wordstor[0]);
  2207. //FEB 2010 TW
  2208. if(!sloom)
  2209. insert_separator_on_sndfile_name(outfilename,2);
  2210. cutendno = 0;
  2211. obuf = dz->sampbuf[0];
  2212. rel_bufend = dz->buflen;
  2213. abs_bufend = dz->buflen;
  2214. rel_bufstart = 0;
  2215. /*origbufsize = dz->bigbufsize; */ /* READ A DOUBLE BUFFER */
  2216. origbuflen = dz->buflen;
  2217. dz->buflen *= 2;
  2218. if((exit_status = read_samps(dz->sampbuf[0],dz)) < 0) {
  2219. sprintf(errstr,"Failed (1) to read input file.\n");
  2220. /*RWD need this here.. */
  2221. free(outfilename);
  2222. return(PROGRAM_ERROR);
  2223. }
  2224. dz->buflen = origbuflen;
  2225. cutendno = 0;
  2226. next_cut = 0;
  2227. abs_bufstart = 0;
  2228. part_splice = 0;
  2229. while(cutendno < dz->iparam[RC_CHCNT]) {
  2230. last_cut = next_cut;
  2231. next_cut = dz->lparray[0][cutendno];
  2232. cutlen = next_cut - last_cut;
  2233. /* FIX: MAR 2003 */
  2234. strcpy(outfilename,dz->wordstor[0]);
  2235. //FEB 2010 TW
  2236. if(!sloom)
  2237. insert_separator_on_sndfile_name(outfilename,2);
  2238. if((exit_status = create_an_outfile(cutendno,cutlen,outfilename,dz))<0) {
  2239. free(outfilename); /*RWD should be done here */
  2240. return(exit_status);
  2241. }
  2242. if(cutendno > 0)
  2243. do_insitu_upsplice(rel_bufstart,dz);
  2244. while(next_cut >= abs_bufend) { /* ?? >= OR > ?? */
  2245. part_splice = 0;
  2246. if(cutendno != dz->iparam[RC_CHCNT]-1) {
  2247. if((part_splice = stereo_splicelen - (next_cut - abs_bufend)) > 0) {
  2248. splice_start = rel_bufend - part_splice;
  2249. do_insitu_splice(splice_start,rel_bufend,0,chans,dz);
  2250. } else {
  2251. part_splice = 0;
  2252. }
  2253. }
  2254. if((exit_status = write_samps(obuf,dz->buflen,dz)) < 0) {
  2255. /* RWD and here..... */
  2256. free(outfilename);
  2257. return(exit_status);
  2258. }
  2259. memcpy((char *)dz->sampbuf[0],(char *)dz->sampbuf[1],dz->buflen * sizeof(float));
  2260. abs_bufend += dz->buflen;
  2261. cutlen -= dz->buflen;
  2262. if((exit_status = read_samps(dz->sampbuf[1],dz)) < 0) {
  2263. /*RWD and here.... */
  2264. free(outfilename);
  2265. return(exit_status);
  2266. }
  2267. }
  2268. rel_cutend = cutlen + rel_bufstart;
  2269. if(cutendno != dz->iparam[RC_CHCNT]-1) {
  2270. if(part_splice > 0) {
  2271. part_splice /= dz->infile->channels;
  2272. do_insitu_splice(rel_bufstart,rel_cutend,part_splice,chans,dz);
  2273. } else {
  2274. do_insitu_splice(rel_cutend - stereo_splicelen,rel_cutend,0,chans,dz);
  2275. }
  2276. }
  2277. if((samps_to_write = rel_cutend - rel_bufstart) > 0) {
  2278. if((exit_status = write_samps(obuf,samps_to_write,dz)) < 0) {
  2279. /*RWD and here.... */
  2280. free(outfilename);
  2281. return(exit_status);
  2282. }
  2283. }
  2284. if((exit_status = close_an_outfile(outfilename,dz)) < 0) {
  2285. /*RWD and here.... */
  2286. free(outfilename);
  2287. return(exit_status);
  2288. }
  2289. abs_bufstart = next_cut;
  2290. abs_bufend = abs_bufstart + dz->buflen;
  2291. if(rel_cutend >= dz->buflen) {
  2292. memcpy((char *)dz->sampbuf[0],(char *)dz->sampbuf[1],dz->buflen * sizeof(float));
  2293. if((exit_status = read_samps(dz->sampbuf[1],dz)) < 0) {
  2294. sprintf(errstr,"Failed (2) to read input file.\n");
  2295. /*RWD and here.... */
  2296. free(outfilename);
  2297. return(PROGRAM_ERROR);
  2298. }
  2299. rel_cutend -= dz->buflen;
  2300. }
  2301. rel_bufstart = rel_cutend;
  2302. rel_bufend = rel_bufstart + dz->buflen;
  2303. obuf = dz->sampbuf[0] + rel_bufstart;
  2304. cutendno++;
  2305. }
  2306. /*RWD and finally here! */
  2307. free(outfilename);
  2308. return(FINISHED);
  2309. }
  2310. /**************************** CLOSE_AN_OUTFILE ****************************/
  2311. int close_an_outfile(char *outfilename,dataptr dz)
  2312. {
  2313. int exit_status;
  2314. dz->process_type = UNEQUAL_SNDFILE; /* allows header to be written */
  2315. dz->outfiletype = SNDFILE_OUT; /* allows header to be written */
  2316. if((exit_status = complete_output(dz))<0) { /* ensures file is truncated */
  2317. /*free(outfilename);*/
  2318. return(exit_status);
  2319. }
  2320. dz->process_type = OTHER_PROCESS; /* restore true status */
  2321. dz->outfiletype = NO_OUTPUTFILE; /* restore true status */
  2322. if((exit_status = reset_peak_finder(dz))<0)
  2323. return(exit_status);
  2324. if(sndcloseEx(dz->ofd) < 0) {
  2325. fprintf(stdout,"WARNING: Can't close output soundfile %s\n",outfilename);
  2326. fflush(stdout);
  2327. }
  2328. /*free(outfilename); */ /*RWD: dangerous! */
  2329. dz->ofd = -1;
  2330. return(FINISHED);
  2331. }
  2332. /**************************** CREATE_AN_OUTFILE ****************************/
  2333. int create_an_outfile(int cutno, int cutlen, char *outfilename, dataptr dz)
  2334. {
  2335. int exit_status;
  2336. int orig_infilesize;
  2337. insert_new_number_at_filename_end(outfilename,cutno,1);
  2338. dz->process_type = EQUAL_SNDFILE; /* allow sndfile to be created */
  2339. orig_infilesize = dz->insams[0];
  2340. fprintf(stdout,"INFO: creating file %s\n",outfilename);
  2341. fflush(stdout);
  2342. if((exit_status = create_sized_outfile(outfilename,dz))<0) {
  2343. sprintf(errstr, "Failed to open file %s\n",outfilename);
  2344. /*free(outfilename);*/
  2345. dz->process_type = OTHER_PROCESS;
  2346. dz->insams[0] = orig_infilesize;
  2347. dz->ofd = -1;
  2348. return(GOAL_FAILED);
  2349. }
  2350. dz->process_type = OTHER_PROCESS;
  2351. dz->insams[0] = orig_infilesize;
  2352. reset_filedata_counters(dz);
  2353. return(FINISHED);
  2354. }
  2355. /**************************** DO_INSITU_UPSPLICE ****************************/
  2356. void do_insitu_upsplice(int rel_bufstart,dataptr dz)
  2357. {
  2358. float *samp = dz->sampbuf[0] + rel_bufstart;
  2359. double val;
  2360. int chans = dz->infile->channels, i, j;
  2361. for(i=0; i < SHRED_SPLICELEN; i++) {
  2362. for(j=0;j<chans;j++) {
  2363. val = (*samp) * (double)i/SHRED_SPLICELEN;
  2364. *samp = (float)val;
  2365. samp++;
  2366. }
  2367. }
  2368. }
  2369. /**************************** DO_INSITU_SPLICE ****************************/
  2370. void do_insitu_splice(int start,int end,int splicecnt,int chans, dataptr dz)
  2371. {
  2372. float *samp = dz->sampbuf[0] + start;
  2373. double val;
  2374. int i;
  2375. int j, k = SHRED_SPLICELEN - splicecnt;
  2376. for(i= start; i < end; i+= chans) {
  2377. k--;
  2378. for(j=0;j<chans;j++) {
  2379. val = (*samp) * (double)k/SHRED_SPLICELEN;
  2380. *samp = (float)val;
  2381. samp++;
  2382. }
  2383. }
  2384. }
  2385. /**************************** GET_LENGTHS ****************************/
  2386. int get_lengths(int stereo_splicelen,dataptr dz)
  2387. {
  2388. int m, n;
  2389. for(m=0,n=1;n< dz->iparam[RC_CHCNT];n++,m++)
  2390. dz->lparray[0][m] = dz->iparam[RC_UNITLEN] * n;
  2391. dz->lparray[0][m] = dz->insams[0];
  2392. if(dz->param >= 0) {
  2393. if(!dz->iparam[RC_SCAT])
  2394. normal_scat(dz); /* 1 */
  2395. else
  2396. heavy_scat(stereo_splicelen,dz);
  2397. }
  2398. return(FINISHED);
  2399. }
  2400. /**************************** NORMAL_SCAT ****************************/
  2401. void normal_scat(dataptr dz)
  2402. {
  2403. double this_scatter;
  2404. int n;
  2405. int chunkscat, total_len = dz->iparam[RC_UNITLEN]; /* 1 */
  2406. int cnt_less_one = dz->iparam[RC_CHCNT] - 1;
  2407. for(n=0;n<cnt_less_one;n++) { /* 2 */
  2408. this_scatter = (drand48() - 0.5) * dz->param[RC_SCAT];
  2409. chunkscat = (int)(this_scatter * dz->iparam[RC_UNITLEN]);
  2410. if(ODD(chunkscat))
  2411. chunkscat--; /* 3 */
  2412. dz->lparray[0][n]= total_len + chunkscat;
  2413. total_len += dz->iparam[RC_UNITLEN]; /* 4 */
  2414. }
  2415. dz->lparray[0][n] = dz->insams[0];
  2416. }
  2417. /*********************** HEAVY_SCAT ***************************
  2418. *
  2419. * (1) Start at the chunk (this=1) AFTER the first (which can't be moved).
  2420. * (2) STARTPTR marks the start of the chunk GROUP (and will be advanced
  2421. * by RANGE, which is length of chunk-group).
  2422. * (3) The loop will generate a set of positions for the chunks in
  2423. * a chunk-group. In the first chunkgroup the position of the
  2424. * first chunk (start of file) can't be moved, so loop starts at
  2425. * (first=) 1. Subsequemt loop passes start at 0.
  2426. * (4) For eveery chunk-group.
  2427. * (5) Set the index of the first chunk in this group (start) to the
  2428. * current index (this).
  2429. * (6) For every member of this chunk-group.
  2430. * (7) Generate a random-position within the chunk-grp's range
  2431. * and check it is not too close ( < SPLICELEN) to the others.
  2432. * Set a checking flag (OK).
  2433. * (8) Generate a position within the range, and after the startptr.
  2434. * (9) Compare it with all previously generated positions in this
  2435. * chunk-grp AND with last position of previous chunk-group!!
  2436. * If it's closer than SPLICELEN, set OK = 0, drop out of
  2437. checking loop and generate another position instead.
  2438. * (10) If the position is OK, drop out of position generating loop..
  2439. * (11) Advance to next chunk in this group.
  2440. * (12) Once all this group is done, advance the group startpoint by RANGE.
  2441. * (13) After FIRST grp, all positions can by varied, so set the initial
  2442. * loop counter to (first=)0.
  2443. * (14) If there are chunks left over (endscat!=0)..
  2444. * Follow the same procedure for chunks in end group, using the
  2445. * alternative variables, endscat and endrange.
  2446. */
  2447. void heavy_scat(int stereo_splicelen,dataptr dz)
  2448. {
  2449. int thiss = 1, that, start, n, m, OK; /* 1 */
  2450. int startptr = 0; /* 2 */
  2451. int first = 1; /* 3 */
  2452. int *chunkptr = dz->lparray[0];
  2453. chunkptr[0] = 0;
  2454. for(n=0;n<dz->iparam[RC_SCATGRPCNT];n++) { /* 4 */
  2455. start = thiss; /* 5 */
  2456. for(m=first;m<dz->iparam[RC_SCAT];m++) { /* 6 */
  2457. do { /* 7 */
  2458. OK = 1;
  2459. chunkptr[thiss] = (int)(drand48()*dz->iparam[RC_RANGE]); /* TRUNCATE (?)*/
  2460. chunkptr[thiss] += startptr; /* 8 */
  2461. if(ODD(chunkptr[thiss]))
  2462. chunkptr[thiss]--;
  2463. for(that=start-1; that<thiss; that++) {
  2464. if(abs(chunkptr[thiss] - chunkptr[that])<stereo_splicelen * 2) {
  2465. OK = 0; /* 9 */
  2466. break;
  2467. }
  2468. }
  2469. } while(!OK); /* 10 */
  2470. thiss++; /* 11 */
  2471. }
  2472. startptr += dz->iparam[RC_RANGE]; /* 12 */
  2473. first = 0; /* 13 */
  2474. }
  2475. if(dz->iparam[RC_ENDSCAT]) { /* 14 */
  2476. start = thiss;
  2477. for(m=0;m<dz->iparam[RC_ENDSCAT];m++) {
  2478. do {
  2479. OK = 1;
  2480. chunkptr[thiss] = (int)(drand48() * dz->iparam[RC_ENDRANGE]); /* TRUNCATE (?) */
  2481. chunkptr[thiss] += startptr;
  2482. if(ODD(chunkptr[thiss]))
  2483. chunkptr[thiss]--;
  2484. for(that=start-1; that<thiss; that++) {
  2485. if(abs(chunkptr[thiss] - chunkptr[that])<stereo_splicelen * 2) {
  2486. OK = 0;
  2487. break;
  2488. }
  2489. }
  2490. } while(!OK);
  2491. thiss++;
  2492. }
  2493. }
  2494. ptr_sort(thiss,dz);
  2495. }
  2496. /************************** PTR_SORT ***************************/
  2497. void ptr_sort(int end,dataptr dz)
  2498. {
  2499. int i,j;
  2500. int a;
  2501. int *chunkptr = dz->lparray[0];
  2502. for(j=1;j<end;j++) {
  2503. a = chunkptr[j];
  2504. i = j-1;
  2505. while(i >= 0 && chunkptr[i] > a) {
  2506. chunkptr[i+1]=chunkptr[i];
  2507. i--;
  2508. }
  2509. chunkptr[i+1] = a;
  2510. }
  2511. for(i=0, j=1; j < dz->iparam[RC_CHCNT]; i++, j++)
  2512. chunkptr[i] = chunkptr[j];
  2513. chunkptr[dz->iparam[RC_CHCNT]-1] = dz->insams[0];
  2514. }
  2515. /************************** DO_RANDCHUNKS ***************************/
  2516. int do_randchunks(dataptr dz)
  2517. {
  2518. double range, multiplier, total, addrange;
  2519. int rangecnt;
  2520. initrand48();
  2521. if(dz->param[MINCHUNK] > dz->param[MAXCHUNK])
  2522. swap(&dz->param[MINCHUNK],&dz->param[MAXCHUNK]);
  2523. range = dz->duration - dz->param[MINCHUNK];
  2524. if(range > dz->param[MAXCHUNK])
  2525. range = dz->param[MAXCHUNK];
  2526. if(dz->vflag[FROMSTART])
  2527. return do_fromstart(dz);
  2528. if(dz->vflag[LINEAR]) {
  2529. if((rangecnt = (int)(range/MINOUTDUR))<1) {
  2530. fprintf(stdout,"INFO: incompatible source duration and MINIMUM PERMITTED DUR %.2lf\n",MINOUTDUR);
  2531. return(GOAL_FAILED);
  2532. }
  2533. if(rangecnt < dz->iparam[CHUNKCNT])
  2534. addrange = (range - dz->param[MINCHUNK])/dz->iparam[CHUNKCNT];
  2535. else
  2536. addrange = (range - dz->param[MINCHUNK])/rangecnt;
  2537. return do_linear(dz,range,rangecnt,addrange);
  2538. } else {
  2539. multiplier = 1.5;
  2540. rangecnt = dz->iparam[CHUNKCNT];
  2541. while(dz->iparam[CHUNKCNT] < rangecnt) {
  2542. rangecnt = 1;
  2543. total = dz->param[MINCHUNK];
  2544. addrange = MINOUTDUR;
  2545. multiplier += .5;
  2546. while(total < range) {
  2547. total += addrange;
  2548. addrange *= multiplier;
  2549. rangecnt++;
  2550. }
  2551. rangecnt--;
  2552. }
  2553. return do_nonlinear(dz,range,rangecnt,multiplier);
  2554. }
  2555. }
  2556. /************************** DO_LINEAR ***************************/
  2557. int do_linear(dataptr dz,double range,int rangecnt,double addrange)
  2558. { int m = 0, n, count, exit_status;
  2559. double mindur = dz->param[MINCHUNK];
  2560. double thisrange = dz->param[MINCHUNK], totalrange, k, thislength;
  2561. thislength = thisrange;
  2562. count = dz->iparam[CHUNKCNT];
  2563. for(n=0;n<count;n++) {
  2564. if(m >= rangecnt || thisrange >= range) {
  2565. m = 0;
  2566. thislength = thisrange = mindur;
  2567. }
  2568. totalrange = dz->duration - thisrange;
  2569. k = drand48() * totalrange;
  2570. if((exit_status = cut_chunk(dz,k,k+thislength,n))<0)
  2571. return(exit_status);
  2572. m++;
  2573. thisrange += addrange;
  2574. thislength = thisrange - (addrange * drand48() * 0.5);
  2575. }
  2576. return(FINISHED);
  2577. }
  2578. /************************** DO_NONLINEAR ***************************/
  2579. int do_nonlinear(dataptr dz,double range,int rangecnt,double multiplier)
  2580. { int m = 0, n, count, exit_status;
  2581. double mindur = dz->param[MINCHUNK];
  2582. double thislength, thisrange = dz->param[MINCHUNK];
  2583. double addrange = dz->param[MINCHUNK], totalrange, k;
  2584. thislength = thisrange;
  2585. count = dz->iparam[CHUNKCNT];
  2586. for(n=0;n<count;n++) {
  2587. if(m >= rangecnt || thisrange >= range) {
  2588. m = 0;
  2589. thislength = thisrange = mindur;
  2590. addrange = mindur;
  2591. }
  2592. totalrange = dz->duration - thisrange;
  2593. k = drand48() * totalrange;
  2594. if((exit_status = cut_chunk(dz,k,k+thislength,n))<0)
  2595. return(exit_status);
  2596. m++;
  2597. thisrange += addrange;
  2598. thislength = thisrange - (addrange * drand48() * 0.5);
  2599. addrange *= multiplier;
  2600. }
  2601. return(FINISHED);
  2602. }
  2603. /************************** DO_FROMSTART ***************************/
  2604. int do_fromstart(dataptr dz)
  2605. {
  2606. int n, count,exit_status;
  2607. double mindur = dz->param[MINCHUNK], maxdur = dz->param[MAXCHUNK];
  2608. double k = 0.0, range = dz->param[MAXCHUNK] - dz->param[MINCHUNK], outdur, step;
  2609. count = dz->iparam[CHUNKCNT];
  2610. switch(dz->vflag[LINEAR]) {
  2611. case(0):
  2612. for(n=0;n<count;n++) {
  2613. k = drand48() * range;
  2614. if((exit_status = cut_chunk(dz,0.0,k+mindur,n))<0)
  2615. return(exit_status);
  2616. }
  2617. break;
  2618. case(1):
  2619. if((exit_status = cut_chunk(dz,0.0,mindur,0))<0)
  2620. return(exit_status);
  2621. outdur = mindur;
  2622. step = range/(double)(count-2);
  2623. count--;
  2624. for(n=1;n<count;n++) {
  2625. k = drand48() * step;
  2626. if((exit_status = cut_chunk(dz,0.0,outdur + k,n))<0)
  2627. return(exit_status);
  2628. outdur += step;
  2629. }
  2630. if((exit_status = cut_chunk(dz,0.0,maxdur,n))<0)
  2631. return(exit_status);
  2632. break;
  2633. default:
  2634. fprintf(stderr,"\nImpossible!!! invalid value of 'linear'");
  2635. break;
  2636. }
  2637. return(FINISHED);
  2638. }
  2639. /************************** CUT_CHUNK ***************************/
  2640. int cut_chunk(dataptr dz,double startcut,double endcut,int count)
  2641. {
  2642. int exit_status;
  2643. int origprocess = dz->process, origmode = dz->mode, namelen, numlen = 1;
  2644. char *outfilename;
  2645. char *p, *q, *r;
  2646. if(!sloom) {
  2647. namelen = strlen(dz->wordstor[0]);
  2648. q = dz->wordstor[0];
  2649. r = dz->wordstor[0] + namelen;
  2650. p = r - 1;
  2651. /*RWD 6:2001 added trap for ':' */
  2652. while((*p != '\\') && (*p != '/') && (*p != ':')) {
  2653. p-- ;
  2654. if(p < dz->wordstor[0])
  2655. break;
  2656. }
  2657. if(p > dz->wordstor[0]) {
  2658. p++;
  2659. while(p <= r)
  2660. *q++ = *p++;
  2661. }
  2662. }
  2663. dz->process = EDIT_CUT;
  2664. dz->mode = EDIT_SECS;
  2665. dz->param[CUT_CUT] = startcut;
  2666. dz->param[CUT_END] = endcut;
  2667. dz->param[CUT_SPLEN] = EDIT_SPLICELEN;
  2668. namelen = strlen(dz->wordstor[0]);
  2669. namelen--;
  2670. if(count > 99)
  2671. numlen = 3;
  2672. else if(count > 9)
  2673. numlen = 2;
  2674. reset_filedata_counters(dz);
  2675. if((outfilename = (char *)malloc((namelen + numlen + 1) * sizeof(char)))==NULL) {
  2676. sprintf(errstr,"INSUFFICIENT MEMORY for outfilename.\n");
  2677. return(MEMORY_ERROR);
  2678. }
  2679. strcpy(outfilename,dz->wordstor[0]);
  2680. insert_new_number_at_filename_end(outfilename,count,1);
  2681. dz->process_type = UNEQUAL_SNDFILE; /* allow sndfile to be created */
  2682. dz->outfiletype = SNDFILE_OUT; /* allows header to be written */
  2683. if((exit_status = create_sized_outfile(outfilename,dz))<0)
  2684. return(exit_status);
  2685. if((exit_status = edit_pconsistency(dz))<0)
  2686. return exit_status;
  2687. if((exit_status = edit_preprocess(dz))<0)
  2688. return exit_status;
  2689. if((exit_status = do_cut(dz))<0)
  2690. return exit_status;
  2691. if((exit_status = complete_output(dz))<0)
  2692. return(exit_status);
  2693. if((exit_status = reset_peak_finder(dz))<0)
  2694. return(exit_status);
  2695. if(sndcloseEx(dz->ofd) < 0) {
  2696. fprintf(stdout,"WARNING: Can't close output soundfile %s\n",outfilename);
  2697. fflush(stdout);
  2698. }
  2699. dz->process_type = OTHER_PROCESS;
  2700. dz->outfiletype = NO_OUTPUTFILE; /* restore true status */
  2701. free(outfilename);
  2702. dz->ofd = -1;
  2703. dz->process = origprocess;
  2704. dz->mode = origmode;
  2705. return(FINISHED);
  2706. }
  2707. /************************** CUT_MANY ***************************/
  2708. int cut_many(dataptr dz)
  2709. {
  2710. float *ibuf, *obuf;
  2711. char filename[64];
  2712. int k, startsplice, endsplice;
  2713. int startcut, endcut, samps_left, startseek, offset;
  2714. int outcnt = 0, n = 0, splice_start, samps_to_write, samps_written;
  2715. int exit_status;
  2716. int last_fileout = (dz->itemcnt/2) - 1;
  2717. while(n < dz->itemcnt) {
  2718. if(outcnt > 0) {
  2719. strcpy(filename,dz->wordstor[0]);
  2720. if(sloom)
  2721. insert_new_number_at_filename_end(filename,outcnt,1);
  2722. else
  2723. insert_new_number_at_filename_end(filename,outcnt+1,0);
  2724. if((exit_status = create_sized_outfile(filename,dz))<0) {
  2725. sprintf(errstr, "ERROR: Soundfile %s already exists: cannot proceed further\n", filename);
  2726. return(exit_status);
  2727. }
  2728. }
  2729. startcut = dz->lparray[0][n++];
  2730. endcut = dz->lparray[0][n++];
  2731. samps_left = endcut - startcut;
  2732. startsplice = (samps_left - dz->iparam[CM_SPLICE_TOTSAMPS]) % dz->buflen;
  2733. startseek = (startcut/F_SECSIZE) * F_SECSIZE;
  2734. offset = startcut - startseek;
  2735. sndseekEx(dz->ifd[0],startseek,0);
  2736. ibuf = dz->bigbuf;
  2737. obuf = ibuf + offset;
  2738. dz->buflen += F_SECSIZE;
  2739. if((exit_status = read_samps(ibuf,dz))<0)
  2740. return(SYSTEM_ERROR);
  2741. dz->buflen -= F_SECSIZE;
  2742. ibuf += F_SECSIZE;
  2743. k = 0;
  2744. splice_start = 0;
  2745. dz->total_samps_written = 0;
  2746. do {
  2747. samps_to_write = min(samps_left,dz->buflen);
  2748. if(k == 0)
  2749. splice_obuf_start(obuf,dz);
  2750. if(samps_left < dz->buflen + dz->iparam[CM_SPLICE_TOTSAMPS]) {
  2751. if(splice_start == 0) {
  2752. if((endsplice = startsplice + dz->iparam[CM_SPLICE_TOTSAMPS]) <= dz->buflen) {
  2753. splice_obuf_end(obuf,&splice_start,startsplice,endsplice,dz);
  2754. } else {
  2755. splice_obuf_end(obuf,&splice_start,startsplice,dz->buflen,dz);
  2756. }
  2757. } else {
  2758. splice_obuf_end(obuf,&splice_start,0,samps_left,dz);
  2759. }
  2760. }
  2761. if(samps_to_write > 0) {
  2762. if((exit_status = write_samps_no_report(obuf,samps_to_write,&samps_written,dz))<0)
  2763. return(exit_status);
  2764. }
  2765. if((samps_left -= samps_to_write) > 0) {
  2766. memcpy((char *)obuf,(char *)(obuf + dz->buflen),(F_SECSIZE - offset) * sizeof(float));
  2767. if((exit_status = read_samps(ibuf,dz))<0)
  2768. return(exit_status);
  2769. }
  2770. k++;
  2771. } while(samps_left > 0);
  2772. if(outcnt != last_fileout) {
  2773. if((exit_status = headwrite(dz->ofd,dz))<0)
  2774. return(exit_status);
  2775. if((exit_status = reset_peak_finder(dz))<0)
  2776. return(exit_status);
  2777. if(sndcloseEx(dz->ofd)<0) {
  2778. sprintf(errstr,"Failed to close output soundfile.\n");
  2779. return(SYSTEM_ERROR);
  2780. }
  2781. dz->ofd = -1;
  2782. }
  2783. outcnt++;
  2784. display_virtual_time(outcnt,dz);
  2785. }
  2786. return(FINISHED);
  2787. }
  2788. /************************** SPLICE_OBUF_START ***************************/
  2789. void splice_obuf_start(float *obuf,dataptr dz)
  2790. {
  2791. int n, m;
  2792. double aincr = dz->param[CM_SPLICEINCR];
  2793. double mult = 0;
  2794. int chans = dz->infile->channels;
  2795. int splicelen = dz->iparam[CM_SPLICESAMPS] * dz->infile->channels;
  2796. for(n = 0;n < splicelen; n+=chans) {
  2797. for(m = 0;m < chans; m++)
  2798. obuf[n+m] = (float)(obuf[n+m] * mult);
  2799. mult += aincr;
  2800. }
  2801. }
  2802. /************************** SPLICE_OBUF_END ***************************/
  2803. void splice_obuf_end(float *obuf,int *splice_start,int startsamp,int endsamp,dataptr dz)
  2804. {
  2805. int n, m;
  2806. double aincr = dz->param[CM_SPLICEINCR];
  2807. double mult = 1.0 - (aincr * (*splice_start + 1));
  2808. int chans = dz->infile->channels;
  2809. int splicelen = (endsamp - startsamp)/chans;
  2810. for(n = startsamp;n < endsamp; n+=chans) {
  2811. for(m = 0;m < chans; m++)
  2812. obuf[n+m] = (float)(obuf[n+m] * mult);
  2813. mult -= aincr;
  2814. }
  2815. *splice_start += splicelen;
  2816. }
  2817. /********************************** DO_NOISE_SUPPRESSION **********************************
  2818. *
  2819. * Creating envelope to splice out non_pitched material based on wavset-len,
  2820. * and eliminating any bits of tone which are too short
  2821. */
  2822. int do_noise_suppression(dataptr dz)
  2823. {
  2824. float *ibuf = dz->sampbuf[0];
  2825. int getnextbuf = 0, phase, isnoise = -1, doincr, noisefirst = 0, spliceafter;
  2826. int in_noise = 0, in_splice = 0, OK, exit_status;
  2827. int j, k, n = 0, m, nextpoint, splice_cnt, edit_position, next_edit_position;
  2828. int twosplices;
  2829. int brkpntcnt = 0, last_total_samps_read = 0, lastzcross = 0;
  2830. double splincr;
  2831. int thispos, lastpos = 0;
  2832. splincr = 1.0/(double)dz->iparam[NOISE_SPLEN];
  2833. if((exit_status = read_samps(ibuf,dz))<0)
  2834. return(exit_status);
  2835. else if(dz->ssampsread <= 0) {
  2836. sprintf(errstr,"Failed to read sound from input file\n");
  2837. return(DATA_ERROR);
  2838. }
  2839. /* ESTABLISH INITIAL PHASE OF SIGNAL */
  2840. do {
  2841. if(dz->ssampsread <= 0)
  2842. break;
  2843. n = 0;
  2844. getnextbuf = 0;
  2845. while(smpflteq(ibuf[n],0.0)) {
  2846. if(++n >= dz->ssampsread) {
  2847. getnextbuf = 1;
  2848. break;
  2849. }
  2850. }
  2851. if(!getnextbuf)
  2852. break;
  2853. last_total_samps_read = dz->total_samps_read;
  2854. } while((exit_status = read_samps(ibuf,dz))>=0);
  2855. if(exit_status < 0)
  2856. return(exit_status);
  2857. if(getnextbuf) {
  2858. sprintf(errstr,"Failed to find any wavecycles in file.\n");
  2859. return(DATA_ERROR);
  2860. }
  2861. if(ibuf[n] > 0.0)
  2862. phase = 0;
  2863. else
  2864. phase = 1;
  2865. /* LOCATE NOISE: non-NOISE SWITCHES */
  2866. for(;;) { /* READ INPUT BUFFERS LOOP */
  2867. for(;;) { /* LOCATE WAVECYCLE IN CURRENT BUFFER, LOOP */
  2868. /* FIND A WAVECYCLE */
  2869. if(phase == 0) {
  2870. while(ibuf[n] > 0.0) {
  2871. if(++n >= dz->ssampsread) {
  2872. getnextbuf = 1;
  2873. break;
  2874. }
  2875. }
  2876. if(getnextbuf)
  2877. break;
  2878. while(ibuf[n] <= 0.0) {
  2879. if(++n >= dz->ssampsread) {
  2880. getnextbuf = 1;
  2881. break;
  2882. }
  2883. }
  2884. if(getnextbuf)
  2885. break;
  2886. } else {
  2887. while(ibuf[n] <= 0.0) {
  2888. if(++n >= dz->ssampsread) {
  2889. getnextbuf = 1;
  2890. break;
  2891. }
  2892. }
  2893. if(getnextbuf)
  2894. break;
  2895. while(ibuf[n] > 0.0) {
  2896. if(++n >= dz->ssampsread) {
  2897. getnextbuf = 1;
  2898. break;
  2899. }
  2900. }
  2901. if(getnextbuf)
  2902. break;
  2903. }
  2904. thispos = last_total_samps_read + n;
  2905. doincr = 0;
  2906. /* MEASURE WAVE-CYCLE LENGTH, AND TEST FOR NOISE */
  2907. /* IF SIGNAL SWITCHES FROM NOISE to NOT-NOISE or vice versa, STORE THAT POSITION */
  2908. if(thispos - lastzcross < dz->iparam[NOISE_MINFRQ]) {
  2909. if(isnoise < 0) /* if at signal start ... */
  2910. noisefirst = 1; /* flag signal starts with noise - (don't store position [i.e. count brkpnts] yet) */
  2911. else if(isnoise == 0) { /* elseif switched into noise ... */
  2912. if(brkpntcnt == 0) {
  2913. if(thispos > dz->iparam[MIN_TONELEN]) /* if enough tone present */
  2914. doincr = 1; /* ... --- keep point (i.e. count brkpnt & incr brkpnt pointer) */
  2915. else
  2916. noisefirst = 1;
  2917. } else {
  2918. if(thispos - lastpos > dz->iparam[MIN_TONELEN])
  2919. doincr = 1; /* ... --- keep point (i.e. count brkpnt & incr brkpnt pointer) */
  2920. else { /* if NOT ENOUGH tone present */
  2921. brkpntcnt--; /* eliminate the previous breakpoint, which started the tone segment */
  2922. thispos = lastpos;
  2923. }
  2924. }
  2925. }
  2926. isnoise = 1;
  2927. } else {
  2928. if(isnoise < 0) /* if at signal start ... */
  2929. noisefirst = 0; /* flag signal doesn't start with noise - (don't store position [i.e. count brkpnts] yet) */
  2930. else if(isnoise == 1) { /* elseif switched out of noise ... */
  2931. if(brkpntcnt == 0) {
  2932. if(thispos > dz->iparam[MIN_NOISLEN])
  2933. doincr = 1;
  2934. else
  2935. noisefirst = 0;
  2936. } else { /* if enough noise present ... */
  2937. if(thispos - lastpos > dz->iparam[MIN_NOISLEN])
  2938. doincr = 1; /* ....--- keep point (i.e. count brkpnt & incr brkpnt pointer) */
  2939. else { /* if NOT ENOUGH noise present */
  2940. brkpntcnt--; /* eliminate the previous breakpoint, which started the noise segment */
  2941. thispos = lastpos;
  2942. }
  2943. }
  2944. }
  2945. isnoise = 0;
  2946. } /* store position of last waveset end... */
  2947. lastzcross = thispos; /* regardless of whether position is stored in brkpnt array */
  2948. if(doincr) { /* if point retained in brkpoint array, move along array */
  2949. lastpos = thispos;
  2950. brkpntcnt++;
  2951. }
  2952. } /* READ NEXT BUFFER */
  2953. last_total_samps_read = dz->total_samps_read;
  2954. if((exit_status = read_samps(ibuf,dz)) < 0)
  2955. return(exit_status);
  2956. else if(dz->ssampsread <= 0)
  2957. break;
  2958. n = 0;
  2959. getnextbuf = 0;
  2960. }
  2961. //TW ADDED TEST BEFORE MALLOCS ATTEMPTED: JULY 2006
  2962. if(brkpntcnt<=1) {
  2963. if(isnoise) {
  2964. sprintf(errstr,"Sound is all noise.");
  2965. return(GOAL_FAILED);
  2966. } else {
  2967. sprintf(errstr,"Sound has no noise.");
  2968. return(GOAL_FAILED);
  2969. }
  2970. }
  2971. //TW late july :TO AVOID realooc PROBLEMS, GRAB THE DOUBLE WADGE OF MEMORY HERE
  2972. if((dz->lparray[0] = (int *)malloc(brkpntcnt * 2 * sizeof(int)))==NULL) {
  2973. sprintf(errstr,"Insufficient memory for edit points.");
  2974. return(MEMORY_ERROR);
  2975. }
  2976. sndseekEx(dz->ifd[0],0,0);
  2977. //TW RESET VARIABLE BELOW
  2978. last_total_samps_read = 0;
  2979. reset_filedata_counters(dz);
  2980. brkpntcnt = 0;
  2981. if((exit_status = read_samps(ibuf,dz))<0)
  2982. return(exit_status);
  2983. else if(dz->ssampsread <= 0) {
  2984. sprintf(errstr,"Failed to read sound from input file\n");
  2985. return(DATA_ERROR);
  2986. }
  2987. do {
  2988. if(dz->ssampsread <= 0)
  2989. break;
  2990. n = 0;
  2991. getnextbuf = 0;
  2992. while(smpflteq(ibuf[n],0.0)) {
  2993. if(++n >= dz->ssampsread) {
  2994. getnextbuf = 1;
  2995. break;
  2996. }
  2997. }
  2998. if(!getnextbuf)
  2999. break;
  3000. last_total_samps_read = dz->total_samps_read;
  3001. } while((exit_status = read_samps(ibuf,dz))>=0);
  3002. if(exit_status < 0)
  3003. return(exit_status);
  3004. if(getnextbuf) {
  3005. sprintf(errstr,"Failed to find any wavecycles in file.\n");
  3006. return(DATA_ERROR);
  3007. }
  3008. if(ibuf[n] > 0.0)
  3009. phase = 0;
  3010. else
  3011. phase = 1;
  3012. /* LOCATE NOISE: non-NOISE SWITCHES */
  3013. for(;;) { /* READ INPUT BUFFERS LOOP */
  3014. for(;;) { /* LOCATE WAVECYCLE IN CURRENT BUFFER, LOOP */
  3015. /* FIND A WAVECYCLE */
  3016. if(phase == 0) {
  3017. while(ibuf[n] > 0.0) {
  3018. if(++n >= dz->ssampsread) {
  3019. getnextbuf = 1;
  3020. break;
  3021. }
  3022. }
  3023. if(getnextbuf)
  3024. break;
  3025. while(ibuf[n] <= 0.0) {
  3026. if(++n >= dz->ssampsread) {
  3027. getnextbuf = 1;
  3028. break;
  3029. }
  3030. }
  3031. if(getnextbuf)
  3032. break;
  3033. } else {
  3034. while(ibuf[n] <= 0.0) {
  3035. if(++n >= dz->ssampsread) {
  3036. getnextbuf = 1;
  3037. break;
  3038. }
  3039. }
  3040. if(getnextbuf)
  3041. break;
  3042. while(ibuf[n] > 0.0) {
  3043. if(++n >= dz->ssampsread) {
  3044. getnextbuf = 1;
  3045. break;
  3046. }
  3047. }
  3048. if(getnextbuf)
  3049. break;
  3050. }
  3051. dz->lparray[0][brkpntcnt] = last_total_samps_read + n;
  3052. doincr = 0;
  3053. /* MEASURE WAVE-CYCLE LENGTH, AND TEST FOR NOISE */
  3054. /* IF SIGNAL SWITCHES FROM NOISE to NOT-NOISE or vice versa, STORE THAT POSITION */
  3055. if(dz->lparray[0][brkpntcnt] - lastzcross < dz->iparam[NOISE_MINFRQ]) {
  3056. if(isnoise < 0) /* if at signal start ... */
  3057. noisefirst = 1; /* flag signal starts with noise - (don't store position [i.e. count brkpnts] yet) */
  3058. else if(isnoise == 0) { /* elseif switched into noise ... */
  3059. if(brkpntcnt == 0) {
  3060. if(dz->lparray[0][brkpntcnt] > dz->iparam[MIN_TONELEN]) /* if enough tone present */
  3061. doincr = 1; /* ... --- keep point (i.e. count brkpnt & incr brkpnt pointer) */
  3062. else
  3063. noisefirst = 1;
  3064. } else {
  3065. if(dz->lparray[0][brkpntcnt] - dz->lparray[0][brkpntcnt-1] > dz->iparam[MIN_TONELEN])
  3066. doincr = 1; /* ... --- keep point (i.e. count brkpnt & incr brkpnt pointer) */
  3067. else /* if NOT ENOUGH tone present */
  3068. brkpntcnt--; /* eliminate the previous breakpoint, which started the tone segment */
  3069. }
  3070. }
  3071. isnoise = 1;
  3072. } else {
  3073. if(isnoise < 0) /* if at signal start ... */
  3074. noisefirst = 0; /* flag signal doesn't start with noise - (don't store position [i.e. count brkpnts] yet) */
  3075. else if(isnoise == 1) { /* elseif switched out of noise ... */
  3076. if(brkpntcnt == 0) {
  3077. if(dz->lparray[0][brkpntcnt] > dz->iparam[MIN_NOISLEN])
  3078. doincr = 1;
  3079. else
  3080. noisefirst = 0;
  3081. } else { /* if enough noise present ... */
  3082. if(dz->lparray[0][brkpntcnt] - dz->lparray[0][brkpntcnt-1] > dz->iparam[MIN_NOISLEN])
  3083. doincr = 1; /* ....--- keep point (i.e. count brkpnt & incr brkpnt pointer) */
  3084. else /* if NOT ENOUGH noise present */
  3085. brkpntcnt--; /* eliminate the previous breakpoint, which started the noise segment */
  3086. }
  3087. }
  3088. isnoise = 0;
  3089. } /* store position of last waveset end... */
  3090. lastzcross = dz->lparray[0][brkpntcnt]; /* regardless of whether position is stored in brkpnt array */
  3091. if(doincr) /* if point retained in brkpoint array, move along array */
  3092. ++brkpntcnt;
  3093. } /* READ NEXT BUFFER */
  3094. last_total_samps_read = dz->total_samps_read;
  3095. if((exit_status = read_samps(ibuf,dz))<0)
  3096. return(exit_status);
  3097. else if(dz->ssampsread <= 0)
  3098. break;
  3099. n = 0;
  3100. getnextbuf = 0;
  3101. }
  3102. /* CHECK THAT ANY NOISE : non-NOISE SWITCHES FOUND */
  3103. if(brkpntcnt<=1) {
  3104. if(isnoise) {
  3105. sprintf(errstr,"Sound is all noise.");
  3106. return(GOAL_FAILED);
  3107. } else {
  3108. sprintf(errstr,"Sound has no noise.");
  3109. return(GOAL_FAILED);
  3110. }
  3111. }
  3112. /* ELIMINATE ANY TONE-SEGS SHORTER THAN 2 SPLICELENS */
  3113. twosplices = (dz->iparam[NOISE_SPLEN] * 2);
  3114. if(noisefirst)
  3115. k = 1;
  3116. else
  3117. k = 2;
  3118. for(n=k;n<brkpntcnt;n++) {
  3119. if(dz->lparray[0][n] - dz->lparray[0][n-1] <= twosplices) {
  3120. for(j=n+1,m=n-1;j<brkpntcnt;j++,m++)
  3121. dz->lparray[0][m] =dz->lparray[0][j];
  3122. brkpntcnt -= 2;
  3123. n -= 2;
  3124. }
  3125. }
  3126. /* ADD SPLICE STARTS AND ENDS TO ARRAY of SWITCH-POINTS */
  3127. //TW: late july : AVOID realloc PROBLEMS ... EXTRA SPACE INCLUDED IM INITIAL malloc INSTERAD OF ADDING IT HERE
  3128. // if((dz->lparray[0] = (int *)realloc(dz->lparray[0],brkpntcnt * 2 * sizeof(int)))==NULL) {
  3129. // sprintf(errstr,"No more memory for splice points.");
  3130. // return(MEMORY_ERROR);
  3131. // }
  3132. if((noisefirst && EVEN(brkpntcnt)) || (!noisefirst && ODD(brkpntcnt))) /* ends with noise */
  3133. spliceafter = 0;
  3134. else /* ends with tone */
  3135. spliceafter = 1;
  3136. for(n = brkpntcnt-1; n >= 0; n--) {
  3137. m = n * 2;
  3138. if(spliceafter) {
  3139. dz->lparray[0][m] = dz->lparray[0][n];
  3140. dz->lparray[0][m+1] = dz->lparray[0][n] + dz->iparam[NOISE_SPLEN];
  3141. } else {
  3142. dz->lparray[0][m+1] = dz->lparray[0][n];
  3143. dz->lparray[0][m] = dz->lparray[0][n] - dz->iparam[NOISE_SPLEN];
  3144. }
  3145. spliceafter = !spliceafter;
  3146. }
  3147. brkpntcnt *= 2;
  3148. /* ELIMINATE BAD POINTS AT START OR END */
  3149. /* as original [noise to non-noise ot vice versa] pts MUST lie within sound..... */
  3150. if(dz->lparray[0][0] < 0) { /* 1st splice can start BEFORE snd start only if it's a 'splicebefore' */
  3151. /* from tone->noise at start of sound, and that tone is too short */
  3152. for(j=0,n=2;n < brkpntcnt;n++,j++) /* eliminate it by eliminating opening splice */
  3153. dz->lparray[0][j] = dz->lparray[0][n];
  3154. brkpntcnt -= 2; /* AND indicating sounds now starts with noise */
  3155. noisefirst = 1;
  3156. } /* final splice can end AFTER sound end only if it's a 'spliceafter' */
  3157. /* from noise->tone at end of sound, and that tone is too short */
  3158. /* so, by eliminating last splice, we eliminate that tone */
  3159. if(dz->lparray[0][brkpntcnt-1] > dz->insams[0])
  3160. brkpntcnt -= 2;
  3161. if(brkpntcnt<=2) {
  3162. if(isnoise) {
  3163. sprintf(errstr,"Sound is all noise.");
  3164. return(GOAL_FAILED);
  3165. } else {
  3166. sprintf(errstr,"Sound has no noise.");
  3167. return(GOAL_FAILED);
  3168. }
  3169. }
  3170. /* RETAIN SPLICE STARTS ONLY */
  3171. for(n=1,m=2;m <brkpntcnt;n++, m+=2)
  3172. dz->lparray[0][n] = dz->lparray[0][m];
  3173. brkpntcnt = n;
  3174. /* NOW EDIT SOUND */
  3175. sndseekEx(dz->ifd[0],0,0);
  3176. dz->total_samps_read = 0;
  3177. display_virtual_time(0,dz);
  3178. in_splice = 0;
  3179. splice_cnt = 0;
  3180. if(dz->vflag[GET_NOISE])
  3181. noisefirst = !noisefirst;
  3182. if(noisefirst)
  3183. in_noise = 1;
  3184. else
  3185. in_noise = 0;
  3186. k = -1;
  3187. OK = JUST_CONTINUE;
  3188. /* BUFFER READING:WRITING LOOP */
  3189. while(OK == JUST_CONTINUE) {
  3190. last_total_samps_read = dz->total_samps_read;
  3191. if((exit_status = read_samps(ibuf,dz))<0)
  3192. return(exit_status); /* reads first, or subsequent buffer */
  3193. else if(dz->ssampsread <= 0) {
  3194. OK = CUTOFF_OUTPUT; /* if infile exhausted, flag no more output file here */
  3195. break; /* which means we can break from read loop WITHOUT writing more data */
  3196. }
  3197. edit_position = 0; /* point to start of buffer, earliest position where edits can take effect */
  3198. if(in_splice) { /* if editing process has begun before start of this buffer */
  3199. /* .... and we're in midst of a splice at start of buffer, complete splice */
  3200. /* (guaranteed to be completed within current buffer, due to bufsize checks) */
  3201. in_splice = do_alternating_splices(&in_noise,&splice_cnt,&edit_position,splincr,dz);
  3202. k++;
  3203. }
  3204. /* EDITING OF CURRENT BUFFER, LOOP */
  3205. for(;;) {
  3206. if(in_splice) /* If a splice fails to finish during treatment of current buffer ... */
  3207. break; /* .... we must be at end of buffer, so break from buffer-editing loop */
  3208. if(++k >= brkpntcnt) { /* if there are no more editpoints to read ... */
  3209. if(in_noise) { /* this indicates final seg is noise */
  3210. dz->ssampsread = edit_position; /* so we can curtail outfile to START of this final [edited out] noise seg */
  3211. OK = CUTOFF_OUTPUT;
  3212. } else /* otherwise, final segment is retainable signal */
  3213. OK = WRITERESTOF_INPUT; /* so flag that we want to write the rest of input to output */
  3214. break; /* in BOTH cases, exit from the buffer-editing loop */
  3215. } else /* else, get next edit point */
  3216. nextpoint = dz->lparray[0][k];
  3217. /* if next edit point lies within current buffer */
  3218. if(nextpoint < dz->total_samps_read) {
  3219. next_edit_position = nextpoint - last_total_samps_read; /* get position of edit-point WITHIN buffer */
  3220. if(in_noise) /* remove noise by zeroing signal from previous edit_end to current edit_start */
  3221. memset((char *)(ibuf + edit_position),0,(next_edit_position - edit_position) * sizeof(float));
  3222. edit_position = next_edit_position; /* reset edit_position */
  3223. splice_cnt = 0; /* reset the splice-counter to zero, for new splice */
  3224. /* do-splice, automatically resetting 'in_noise' flag if splice completed */
  3225. /* ...but setting in_splice flag to TRUE if splice NOT completed */
  3226. in_splice = do_alternating_splices(&in_noise,&splice_cnt,&edit_position,splincr,dz);
  3227. } else { /* next edit point lies within current buffer */
  3228. k--; /* restore counter when buffer switches */
  3229. break; /* so, exit buffer-editing loop and go write-output and read next buffer */
  3230. }
  3231. }
  3232. /* EXITED buffer-editing loop */
  3233. /* if still in noise, remove noise at end of buffer */
  3234. if((edit_position < dz->ssampsread) && in_noise)
  3235. memset((char *)(ibuf + edit_position),0,(dz->ssampsread - edit_position) * sizeof(float));
  3236. /* write the edited buffer */
  3237. if(dz->ssampsread > 0) {
  3238. if((exit_status = write_samps(ibuf,dz->ssampsread,dz))< 0)
  3239. return(exit_status);
  3240. } /* go [round loop] to read next buffer */
  3241. }
  3242. if(OK==WRITERESTOF_INPUT) {
  3243. if((exit_status = read_samps(ibuf,dz))<0)
  3244. return(exit_status);
  3245. while(dz->ssampsread > 0) {
  3246. if((exit_status = write_samps(ibuf,dz->ssampsread,dz))< 0)
  3247. return(exit_status);
  3248. if((exit_status = read_samps(ibuf,dz))<0)
  3249. return(exit_status);
  3250. }
  3251. }
  3252. return(FINISHED);
  3253. }
  3254. /********************************** DO_ALTERNATING_SPLICES **********************************/
  3255. int do_alternating_splices(int *in_noise,int *splice_cnt,int *edit_position,double splincr,dataptr dz)
  3256. {
  3257. double newval, spliceval = (double)(*splice_cnt)/(double)dz->iparam[NOISE_SPLEN];
  3258. double this_splincr = splincr;
  3259. if(!(*in_noise)) {
  3260. spliceval = 1.0 - spliceval;
  3261. this_splincr = -this_splincr;
  3262. }
  3263. while(*splice_cnt < dz->iparam[NOISE_SPLEN]) {
  3264. newval = dz->sampbuf[0][*edit_position] * spliceval;
  3265. dz->sampbuf[0][*edit_position] = (float)newval;
  3266. (*edit_position)++;
  3267. (*splice_cnt)++;
  3268. if(*edit_position >= dz->ssampsread)
  3269. break;
  3270. spliceval += this_splincr;
  3271. }
  3272. if(*splice_cnt >= dz->iparam[NOISE_SPLEN]) {
  3273. (*in_noise) = !(*in_noise);
  3274. return(0);
  3275. }
  3276. return(1);
  3277. }
  3278. /********************************** SETUP_INSERT2_OVERWRITE_FLAG **********************************/
  3279. int setup_insert2_overwrite_flag(dataptr dz)
  3280. {
  3281. int flags_needed = INSERT_OVERWRITE + 1;
  3282. if(dz->application->vflag_cnt <= INSERT_OVERWRITE) {
  3283. if(dz->application->vflag_cnt <=0) {
  3284. if((dz->vflag = (char *)malloc(flags_needed * sizeof(char)))==NULL) {
  3285. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  3286. return(MEMORY_ERROR);
  3287. }
  3288. } else {
  3289. if((dz->vflag = (char *)realloc((char *)dz->vflag,flags_needed * sizeof(char)))==NULL) {
  3290. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  3291. return(MEMORY_ERROR);
  3292. }
  3293. }
  3294. }
  3295. dz->vflag[INSERT_OVERWRITE] = 1;
  3296. return FINISHED;
  3297. }
  3298. /*************************** DO_PATTERNED_JOINING *****************************
  3299. *
  3300. * Exactly as do_joining, except for commented stuff.
  3301. */
  3302. int do_patterned_joining(dataptr dz)
  3303. {
  3304. int exit_status;
  3305. int total_fsamps_read, samps_to_get, samps_read, samps_to_write;
  3306. int n, m, k, nextfile, readcnt, lmt = 0;
  3307. int overspill, splice_remnant;
  3308. int tempfile = -1;
  3309. char tempfilename[200];
  3310. int thisifd;
  3311. unsigned int this_size, hold_samps;
  3312. strcpy(tempfilename,dz->wordstor[0]);
  3313. strcat(tempfilename,"_");
  3314. insert_new_number_at_filename_end(tempfilename,dz->infilecnt,0); /* create name for temp file */
  3315. dz->iparam[CUT_SMPSREMAIN] = dz->buflen;
  3316. dz->sampbuf[READBUF] = dz->sampbuf[BBUF];
  3317. if(dz->iparam[CUT_SPLEN]==0)
  3318. lmt = -1;
  3319. for(m=0;m < dz->itemcnt;m++) { /* get next file in pattern */
  3320. if(dz->process == JOIN_SEQ && m >= dz->iparam[MAX_LEN])
  3321. break;
  3322. n = dz->iparray[0][m];
  3323. if(n >= dz->infilecnt) {
  3324. sndseekEx(dz->other_file,0,0);
  3325. fprintf(stdout,"INFO: Processing FILE %d\n",tempfile+1);
  3326. } else { /* reset selected file to start */
  3327. sndseekEx(dz->ifd[n],0,0);
  3328. fprintf(stdout,"INFO: Processing FILE %d\n",n+1);
  3329. }
  3330. fflush(stdout);
  3331. if(m < dz->itemcnt - 1) /* check the succeeding file in the pattern */
  3332. nextfile = dz->iparray[0][m+1];
  3333. else
  3334. nextfile = -1;
  3335. if(n == nextfile) { /* if same file is used contiguously */
  3336. if(tempfile != n) { /* if the temporary file is not the same as this one */
  3337. if(tempfile != -1) {
  3338. char pfname[_MAX_PATH];
  3339. strcpy(pfname, snd_getfilename(dz->other_file));
  3340. sndcloseEx(dz->other_file);
  3341. if(remove(/*outfilename*/pfname)<0) {
  3342. fprintf(stdout,"WARNING: Tempfile %s not removed: ",tempfilename);
  3343. fflush(stdout);
  3344. }
  3345. dz->other_file = -1;
  3346. } /* create a temporary file */
  3347. if((dz->other_file=sndcreat_formatted(tempfilename,dz->insams[n],SAMP_FLOAT,
  3348. dz->infile->channels,dz->infile->srate,CDP_CREATE_NORMAL))<0) {
  3349. sprintf(errstr,"Cannot open temporary file %s: %s\n", tempfilename,sferrstr());
  3350. return(SYSTEM_ERROR);
  3351. } /* copy current file into temporary file */
  3352. do {
  3353. if((samps_read = fgetfbufEx(dz->sampbuf[COPYBUF], dz->buflen,dz->ifd[n],0))<0) {
  3354. sprintf(errstr,"Sound read error.\n");
  3355. return(SYSTEM_ERROR);
  3356. }
  3357. if(samps_read > 0) {
  3358. hold_samps = dz->total_samps_written;
  3359. if((exit_status =
  3360. write_samps_to_elsewhere(dz->other_file,dz->sampbuf[COPYBUF],samps_read,dz))<0) {
  3361. sprintf(errstr, "Can't write copied samples to temporary soundfile: (is hard-disk full?).\n");
  3362. return(SYSTEM_ERROR);
  3363. }
  3364. dz->total_samps_written = hold_samps;
  3365. }
  3366. } while (samps_read > 0);
  3367. memset((char *)dz->sampbuf[COPYBUF],0,dz->buflen * sizeof(float));
  3368. sndseekEx(dz->ifd[n],0,0); /* reset copy buffer (safety only), and current file position */
  3369. tempfile = n; /* remember which file's data is in the temporary file */
  3370. }
  3371. dz->iparray[0][m+1] = dz->infilecnt; /* set up next-file-to-use as the temporary file */
  3372. }
  3373. if(n >= dz->infilecnt) /* if temporary file in use */
  3374. this_size = dz->insams[tempfile]; /* find its size by reference to file copied from */
  3375. else /* else find size of current normal file */
  3376. this_size = dz->insams[n];
  3377. if((samps_to_get = this_size - dz->iparam[CUT_SPLEN])<=0) {
  3378. sprintf(errstr,"File %d is too short for the given splicelength\n",n+1);
  3379. return(GOAL_FAILED);
  3380. }
  3381. total_fsamps_read = 0;
  3382. readcnt = 0;
  3383. for(;;) {
  3384. if(n >= dz->infilecnt) /* if temporary file in use, get its filepointer */
  3385. thisifd = dz->other_file;
  3386. else /* else get filepointer of current file */
  3387. thisifd = dz->ifd[n];
  3388. if((samps_read = fgetfbufEx(dz->sampbuf[READBUF],dz->iparam[CUT_SMPSREMAIN],thisifd,0))<0) {
  3389. sprintf(errstr, "Can't read samples from input soundfile\n");
  3390. return(SYSTEM_ERROR);
  3391. }
  3392. if(dz->process == JOIN_SEQDYN) {
  3393. for(k = 0;k < samps_read; k++)
  3394. dz->sampbuf[READBUF][k] = (float)(dz->sampbuf[READBUF][k] * dz->parray[2][m]);
  3395. }
  3396. overspill = (total_fsamps_read += samps_read) - samps_to_get;
  3397. if(overspill > lmt)
  3398. break;
  3399. if(dz->iparam[CUT_SPLEN]>0 && readcnt==0)
  3400. do_join_startsplice(n,dz);
  3401. if((exit_status = write_exact_samps(dz->sampbuf[BBUF],dz->buflen,dz))<0)
  3402. return(exit_status);
  3403. housekeep2(samps_read,dz);
  3404. readcnt++;
  3405. }
  3406. if(dz->iparam[CUT_SPLEN]>0) {
  3407. if(readcnt==0)
  3408. do_join_startsplice(n,dz);
  3409. housekeep1(samps_read,overspill,dz);
  3410. if((splice_remnant = dz->iparam[CUT_SPLEN] - overspill)>0) {
  3411. if((exit_status = do_join_write(n,splice_remnant,overspill,dz))<0)
  3412. return(exit_status);
  3413. } else {
  3414. if((exit_status = reset_join_buffer_params(dz))<0)
  3415. return(exit_status);
  3416. }
  3417. } else {
  3418. dz->sbufptr[ENDSPLICE_ADDR] = dz->sampbuf[READBUF] + samps_read;
  3419. if((exit_status = reset_join_buffer_params(dz))<0)
  3420. return(exit_status);
  3421. }
  3422. }
  3423. if(dz->iparam[CUT_SPLEN]>0) {
  3424. if(dz->vflag[SPLICE_END])
  3425. do_join_endsplice(dz);
  3426. memcpy((char *)dz->sampbuf[READBUF],(char *)dz->sampbuf[SPLICEBUF],dz->iparam[CUT_SPLEN] * sizeof(float));
  3427. }
  3428. samps_to_write = dz->sampbuf[READBUF] + dz->iparam[CUT_SPLEN] - dz->sampbuf[BBUF];
  3429. if(samps_to_write > 0)
  3430. exit_status = write_samps(dz->sampbuf[BBUF],samps_to_write,dz);
  3431. else
  3432. exit_status = FINISHED;
  3433. if(tempfile != -1) {
  3434. char pfname[_MAX_PATH];
  3435. strcpy(pfname, snd_getfilename(dz->other_file));
  3436. sndcloseEx(dz->other_file);
  3437. if(remove(/*outfilename*/pfname)<0) {
  3438. fprintf(stdout,"WARNING: Tempfile %s not removed: ",tempfilename);
  3439. fflush(stdout);
  3440. }
  3441. dz->other_file = -1;
  3442. }
  3443. return exit_status;
  3444. }
  3445. /*************************** DO_MANY_ZCUTS *****************************/
  3446. int do_many_zcuts(dataptr dz) {
  3447. int exit_status, outcnt, last_fileout = 0;
  3448. char filename[400];
  3449. int n, m;
  3450. outcnt = 0;
  3451. for(n=0,m=0;m < dz->itemcnt;n++,m+=2) {
  3452. if((outcnt > 0) && (last_fileout != outcnt)) {
  3453. strcpy(filename,dz->wordstor[0]);
  3454. if(sloom)
  3455. insert_new_number_at_filename_end(filename,outcnt,1);
  3456. else
  3457. insert_new_number_at_filename_end(filename,outcnt+1,0);
  3458. if((exit_status = create_sized_outfile(filename,dz))<0) {
  3459. sprintf(errstr, "ERROR: Soundfile %s already exists: cannot proceed further\n", filename);
  3460. fflush(stdout);
  3461. }
  3462. }
  3463. dz->iparam[CUT_CUT] = (int)dz->lparray[0][m];
  3464. dz->iparam[CUT_END] = (int)dz->lparray[0][m+1];
  3465. sndseekEx(dz->ifd[0],0,0);
  3466. dz->total_samps_read = 0;
  3467. memset((char *)dz->sampbuf[OBUF],0,dz->buflen * sizeof(float));
  3468. memset((char *)dz->sampbuf[IBUF],0,dz->buflen * sizeof(float));
  3469. if((exit_status = do_zcut(dz)) < 0) {
  3470. fprintf(stdout,"INFO: FAILED TO MAKE EDIT %d\n",n+1);
  3471. fflush(stdout);
  3472. continue;
  3473. } else {
  3474. if((exit_status = headwrite(dz->ofd,dz))<0)
  3475. return(exit_status);
  3476. if((exit_status = reset_peak_finder(dz))<0)
  3477. return(exit_status);
  3478. if(sndcloseEx(dz->ofd)<0) {
  3479. sprintf(errstr,"Failed to close output soundfile.\n");
  3480. return(SYSTEM_ERROR);
  3481. }
  3482. dz->ofd = -1;
  3483. last_fileout = outcnt;
  3484. outcnt++;
  3485. display_virtual_time(outcnt,dz);
  3486. }
  3487. }
  3488. if(outcnt == 0) {
  3489. sprintf(errstr,"NO EDITS MADE");
  3490. return(GOAL_FAILED);
  3491. }
  3492. return FINISHED;
  3493. }