repitch.c 120 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730
  1. /*
  2. * Copyright (c) 1983-2013 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. /* flotsam version */
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <structures.h>
  25. #include <tkglobals.h>
  26. #include <pnames.h>
  27. #include <globcon.h>
  28. #include <processno.h>
  29. #include <modeno.h>
  30. #include <special.h>
  31. #include <logic.h>
  32. #include <arrays.h>
  33. #include <flags.h>
  34. #include <repitch.h>
  35. #include <cdpmain.h>
  36. #include <formants.h>
  37. #include <speccon.h>
  38. #include <sfsys.h>
  39. #include <osbind.h>
  40. #include <repitch.h>
  41. #include <pvoc.h>
  42. #include <vowels.h>
  43. #include <vowels2.h>
  44. #if defined unix || defined __GNUC__
  45. #define round(x) lround((x))
  46. #endif
  47. #define GLARG (0.1) /* 2nd-derivative maximum, for smoothing */
  48. #define SLOPE_FUDGE (0.2)
  49. static int specpitch(dataptr dz);
  50. static int spectrack(dataptr dz);
  51. static int tranpose_within_formant_envelope(int vc,dataptr dz);
  52. static int reposition_partials_in_appropriate_channels(int with_body,dataptr dz);
  53. static int zero_outofrange_channels(double *totalamp,double lofrq_limit,double hifrq_limit,dataptr dz);
  54. static int close_to_frq_already_in_ring(chvptr *there,double frq1,dataptr dz);
  55. static int substitute_in_ring(int vc,chvptr here,chvptr there,dataptr dz);
  56. static int insert_in_ring(int vc, chvptr here, dataptr dz);
  57. static int put_ring_frqs_in_ascending_order(chvptr **partials,float *minamp,dataptr dz);
  58. static int found_pitch(chvptr *partials,double lo_loud_partial,double hi_loud_partial,float minamp,dataptr dz);
  59. static int found_pitch_1(chvptr *partials,double lo_loud_partial,double hi_loud_partial,float minamp,dataptr dz);
  60. static int found_pitch_2(chvptr *partials,dataptr dz);
  61. static int smooth_spurious_octave_leaps(int pitchno,float minamp,dataptr dz);
  62. static int equivalent_pitches(double frq1, double frq2, dataptr dz);
  63. static int is_peak_at(double frq,int window_offset,float minamp,dataptr dz);
  64. static int enough_partials_are_harmonics(chvptr *partials,dataptr dz);
  65. static int is_a_harmonic(double frq1,double frq2,dataptr dz);
  66. static int do_pitch_cut(dataptr dz);
  67. static int do_pitch_filter(dataptr dz);
  68. static int do_pitch_smoothing(dataptr dz);
  69. static int skip_to_first_pitch(int *first_pitch,dataptr dz);
  70. static int calc_slopechanges(int m, double *slopechange,dataptr dz);
  71. static int is_start_of_glitch(int n,double *slopechange,dataptr dz);
  72. static int do_onset_smooth(int n, double *slopechange,dataptr dz);
  73. static int do_double_onset_smooth(int n, double *slopechange,dataptr dz);
  74. static int do_smooth(int n, double *slopechange,dataptr dz);
  75. static int get_max_and_min_pitches(double *maxpitch,double *minpitch,dataptr dz);
  76. static int write_remaining_pitch_or_transpos_data(int final_length_in_windows,dataptr dz);
  77. static int specpapprox(int *,double *,dataptr dz);
  78. static int specpcut(int *,dataptr dz);
  79. static int specpexag(dataptr dz);
  80. static int specpinvert(dataptr dz);
  81. static int specpquantise(dataptr dz);
  82. static int specprand(dataptr dz);
  83. static int specpsmooth(dataptr dz);
  84. static int specptranspose(dataptr dz);
  85. static int specpvib(dataptr dz);
  86. static int get_midimean(double *midimean,dataptr dz);
  87. static int set_pval(double midivalue,int n,dataptr dz);
  88. static int do_tail(int n, double lastmidi,dataptr dz);
  89. static int get_pitchapprox_averages(int *avcnt,dataptr dz);
  90. static int get_rand_interval(double *thisintv,dataptr dz);
  91. static int approx_func1(int *,int *,double *,int *,int n,dataptr dz);
  92. static int approx_func2(int *newlength_of_data,double lastmidi,int lastpos,int avcnt,dataptr dz);
  93. static int interval_mapping(double *thisint,double thismidi,dataptr dz);
  94. static int peak_interp(int pitchno,int last_validpitch_no,int *lastmaxpos,double meanpich,
  95. double minint,double maxint,double *lastmidi,dataptr dz);
  96. static int tidy_up_pitch_data(dataptr dz);
  97. static int generate_tone(dataptr dz);
  98. static int anti_noise_smoothing(int wlength,float *pitches,float frametime);
  99. static int is_smooth_from_both_sides(int n,double max_pglide,float *pitches);
  100. static int is_initialpitch_smooth(char *smooth,double max_pglide,float *pitches);
  101. static int is_finalpitch_smooth(char *smooth,double max_pglide,int wlength,float *pitches);
  102. static int is_smooth_from_before(int n,char *smooth,double max_pglide,float *pitches);
  103. static int is_smooth_from_after(int n,char *smooth,double max_pglide,float *pitches);
  104. static int test_glitch_sets(char *smooth,double max_pglide,int wlength,float *pitches);
  105. static void remove_unsmooth_pitches(char *smooth,int wlength,float *pitches);
  106. static int test_glitch_forwards(int gltchstart,int gltchend,char *smooth,double max_pglide,float *pitches);
  107. static int test_glitch_backwards(int gltchstart,int gltchend,char *smooth,
  108. double max_pglide,int wlength,float *pitches);
  109. /* RWD NB: changes outfile header properties - rejigging required! */
  110. static int write_pitch_outheader_from_analysis_inheader_to_second_outfile(int ofd,dataptr dz);
  111. static int local_peak(int thiscc,double frq, float *thisbuf, dataptr dz);
  112. static int interpolate_pitch(float *floatbuf,int skip_silence,dataptr dz);
  113. static double hz_to_pitchheight(double frqq);
  114. static double pitchheight_to_hz(double pitch_height);
  115. static int eliminate_blips_in_pitch_data(dataptr dz);
  116. static int mark_zeros_in_pitchdata(dataptr dz);
  117. static int pitch_found(dataptr dz);
  118. static int do_interpolating(int *pitchno,float *floatbuf,int skip_silence,dataptr dz);
  119. static void check_transpos(float *t,dataptr dz);
  120. static void check_pitch(float *t,dataptr dz);
  121. static int trap_junk(int final_length_in_windows,dataptr dz);
  122. static int write_pitch_or_transpos_data(int final_length_in_windows,dataptr dz);
  123. static int pitch_insert(int is_sil,dataptr dz);
  124. static int pitch_to_silence(dataptr dz);
  125. static int unpitch_to_silence(dataptr dz);
  126. static int generate_vowels(dataptr dz);
  127. static int generate_vowel_spectrum(double frq,double formant1,double formant2,double formant3,
  128. double f2atten,double f3atten,double *sensitivity,int senslen,int is_offset,dataptr dz);
  129. static int get_formant_frqs(int vowel,double *formant1,double *formant2,double *formant3,
  130. double *f2atten,double *f3atten);
  131. static int define_sensitivity_curve(double **sensitivity,int *senslen);
  132. static int adjust_for_sensitivity(double *amp,double frq,double *sensitivity,int senslen);
  133. static int remove_pitch_zeros(dataptr dz);
  134. static int convert_single_window_pch_or_transpos_data_to_brkpnttable
  135. (int *brksize,float *floatbuf,float frametime,int array_no,dataptr dz);
  136. int are_pitch_zeros = 0;
  137. /********************************** SPECTRNSF **********************************
  138. *
  139. * transpose spectrum, but retain original spectral envelope.
  140. */
  141. int spectrnsf(dataptr dz)
  142. {
  143. int exit_status;
  144. double pre_totalamp, post_totalamp;
  145. double lofrq_limit, hifrq_limit;
  146. int cc, vc;
  147. rectify_window(dz->flbufptr[0],dz);
  148. if((exit_status = extract_specenv(0,0,dz))<0)
  149. return(exit_status);
  150. if((exit_status = get_totalamp(&pre_totalamp,dz->flbufptr[0],dz->wanted))<0)
  151. return(exit_status);
  152. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2) {
  153. if((exit_status = tranpose_within_formant_envelope(vc,dz))<0)
  154. return(exit_status);
  155. }
  156. if((exit_status = reposition_partials_in_appropriate_channels(TRNSF_BODY,dz))<0)
  157. return(exit_status);
  158. if(dz->vflag[TRNSF_FBOT] || dz->vflag[TRNSF_FTOP]) {
  159. lofrq_limit = dz->param[TRNSF_LOFRQ];
  160. hifrq_limit = dz->param[TRNSF_HIFRQ];
  161. if(hifrq_limit < lofrq_limit)
  162. swap(&hifrq_limit,&lofrq_limit);
  163. if((exit_status = zero_outofrange_channels(&post_totalamp,lofrq_limit,hifrq_limit,dz))<0)
  164. return(exit_status);
  165. } else {
  166. if((exit_status = get_totalamp(&post_totalamp,dz->flbufptr[0],dz->wanted))<0)
  167. return(exit_status);
  168. }
  169. return normalise(pre_totalamp,post_totalamp,dz);
  170. }
  171. /********************************** SPECTRNSP **********************************
  172. *
  173. * transpose spectrum, (spectral envelope also moves).
  174. */
  175. int spectrnsp(dataptr dz)
  176. {
  177. int exit_status;
  178. double pre_totalamp, post_totalamp;
  179. double lofrq_limit, hifrq_limit;
  180. int cc, vc;
  181. rectify_window(dz->flbufptr[0],dz);
  182. if((exit_status = get_totalamp(&pre_totalamp,dz->flbufptr[0],dz->wanted))<0)
  183. return(exit_status);
  184. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2)
  185. dz->flbufptr[0][FREQ] = (float)(dz->flbufptr[0][FREQ]*dz->transpos[dz->total_windows]);
  186. if((exit_status = reposition_partials_in_appropriate_channels(TRNSP_BODY,dz))<0)
  187. return(exit_status);
  188. if(dz->vflag[TRNSP_FBOT] || dz->vflag[TRNSP_FTOP]) {
  189. lofrq_limit = dz->param[TRNSP_LOFRQ];
  190. hifrq_limit = dz->param[TRNSP_HIFRQ];
  191. if(hifrq_limit < lofrq_limit)
  192. swap(&hifrq_limit,&lofrq_limit);
  193. if((exit_status = zero_outofrange_channels(&post_totalamp,lofrq_limit,hifrq_limit,dz))<0)
  194. return(exit_status);
  195. } else {
  196. if((exit_status = get_totalamp(&post_totalamp,dz->flbufptr[0],dz->wanted))<0)
  197. return(exit_status);
  198. }
  199. return normalise(pre_totalamp,post_totalamp,dz);
  200. }
  201. /************************** TRANPOSE_WITHIN_FORMANT_ENVELOPE *****************************/
  202. int tranpose_within_formant_envelope(int vc,dataptr dz)
  203. {
  204. int exit_status;
  205. double thisspecamp, newspecamp, thisamp, formantamp_ratio;
  206. if((exit_status = getspecenvamp(&thisspecamp,(double)dz->flbufptr[0][FREQ],0,dz))<0)
  207. return(exit_status);
  208. dz->flbufptr[0][FREQ] = (float)(fabs(dz->flbufptr[0][FREQ])*dz->transpos[dz->total_windows]);
  209. if(dz->flbufptr[0][FREQ] < dz->nyquist) {
  210. if(thisspecamp < VERY_TINY_VAL)
  211. dz->flbufptr[0][AMPP] = 0.0f;
  212. else {
  213. if((exit_status = getspecenvamp(&newspecamp,(double)dz->flbufptr[0][FREQ],0,dz))<0)
  214. return(exit_status);
  215. if(newspecamp < VERY_TINY_VAL)
  216. dz->flbufptr[0][AMPP] = 0.0f;
  217. else {
  218. formantamp_ratio = newspecamp/thisspecamp;
  219. if((thisamp = dz->flbufptr[0][AMPP] * formantamp_ratio) < VERY_TINY_VAL)
  220. dz->flbufptr[0][AMPP] = 0.0f;
  221. else
  222. dz->flbufptr[0][AMPP] = (float)thisamp;
  223. }
  224. }
  225. }
  226. return(FINISHED);
  227. }
  228. /************************ REPOSITION_PARTIALS_IN_APPROPRIATE_CHANNELS *************************
  229. *
  230. * (1) At each pass, preset store-buffer channel amps to zero.
  231. * (2) Move frq data into appropriate channels, carrying the
  232. * amplitude information along with them.
  233. * Work down spectrum for upward transposition, and
  234. * (3) up spectrum for downward transposition,
  235. * so that we do not overwrite transposed data before we move it.
  236. * (4) Put new frqs back into src buff.
  237. */
  238. int reposition_partials_in_appropriate_channels(int with_body,dataptr dz)
  239. {
  240. int exit_status;
  241. int truecc,truevc;
  242. int cc, vc;
  243. for(vc = 0; vc < dz->wanted; vc+=2) /* 1 */
  244. dz->windowbuf[0][vc] = 0.0f;
  245. if(dz->transpos[dz->total_windows] > 1.0f) { /* 2 */
  246. for(cc=dz->clength-1,vc = dz->wanted-2; cc>=0; cc--, vc-=2) {
  247. if(dz->flbufptr[0][FREQ] < dz->nyquist && dz->flbufptr[0][AMPP] > 0.0f) {
  248. if((exit_status = get_channel_corresponding_to_frq(&truecc,(double)dz->flbufptr[0][FREQ],dz))<0)
  249. return(exit_status);
  250. truevc = truecc * 2;
  251. switch(dz->vflag[with_body]) {
  252. case(FALSE):
  253. if((exit_status = move_data_into_appropriate_channel(vc,truevc,dz->flbufptr[0][AMPP],dz->flbufptr[0][FREQ],dz))<0)
  254. return(exit_status);
  255. break;
  256. case(TRUE):
  257. if((exit_status = move_data_into_some_appropriate_channel(truevc,dz->flbufptr[0][AMPP],dz->flbufptr[0][FREQ],dz))<0)
  258. return(exit_status);
  259. break;
  260. default:
  261. sprintf(errstr,"Unknown case for vflag[with_body]: reposition_partials_in_appropriate_channels()\n");
  262. return(PROGRAM_ERROR);
  263. } /* upward transpos, chandata tends to thin */
  264. } /* case(TRUE) tries for fuller spectrum */
  265. }
  266. for(vc = 0; vc < dz->wanted; vc++)
  267. dz->flbufptr[0][vc] = dz->windowbuf[0][vc];
  268. } else if(dz->transpos[dz->total_windows] < 1.0f){ /* 3 */
  269. for(cc=0,vc = 0; cc < dz->clength; cc++, vc+=2) {
  270. if(dz->flbufptr[0][FREQ] < dz->nyquist && dz->flbufptr[0][FREQ]>0.0) {
  271. if((exit_status = get_channel_corresponding_to_frq(&truecc,(double)dz->flbufptr[0][FREQ],dz))<0)
  272. return(exit_status);
  273. truevc = truecc * 2;
  274. if((exit_status = move_data_into_appropriate_channel(vc,truevc,dz->flbufptr[0][AMPP],dz->flbufptr[0][FREQ],dz))<0)
  275. return(exit_status);
  276. }
  277. }
  278. for(vc = 0; vc < dz->wanted; vc++)
  279. dz->flbufptr[0][vc] = dz->windowbuf[0][vc]; /* 4 */
  280. }
  281. return(FINISHED);
  282. }
  283. /******************* ZERO_OUTOFRANGE_CHANNELS *****************/
  284. int zero_outofrange_channels(double *totalamp,double lofrq_limit,double hifrq_limit,dataptr dz)
  285. {
  286. int cc, vc;
  287. *totalamp = 0.0;
  288. for(cc = 0,vc = 0; cc < dz->clength; cc++, vc += 2) {
  289. if(dz->flbufptr[0][FREQ] < lofrq_limit || dz->flbufptr[0][FREQ] > hifrq_limit)
  290. dz->flbufptr[0][AMPP] = 0.0f;
  291. else
  292. *totalamp += dz->flbufptr[0][AMPP];
  293. }
  294. return(FINISHED);
  295. }
  296. /***************************** OUTER_PITCH_LOOP ***********************/
  297. int outer_pitch_loop(dataptr dz)
  298. {
  299. int exit_status;
  300. int samps_read, wc, windows_in_buf, brklen;
  301. double totalamp;
  302. int thismode = 0;
  303. while((samps_read = fgetfbufEx(dz->bigfbuf,dz->big_fsize,dz->ifd[0],0)) > 0) {
  304. dz->flbufptr[0] = dz->bigfbuf;
  305. windows_in_buf = samps_read/dz->wanted;
  306. for(wc=0; wc<windows_in_buf; wc++, dz->total_windows++) {
  307. if(dz->total_windows==0 && dz->wlength > 1) {
  308. dz->pitches[0] = (float)NOT_PITCH;
  309. dz->flbufptr[0] += dz->wanted;
  310. continue;
  311. }
  312. if((exit_status = get_totalamp(&totalamp,dz->flbufptr[0],dz->wanted))<0)
  313. return(exit_status);
  314. dz->parray[PICH_PRETOTAMP][dz->total_windows] = totalamp;
  315. switch(dz->process) {
  316. case(PITCH):
  317. if((exit_status = specpitch(dz))<0)
  318. return(exit_status);
  319. break;
  320. case(TRACK):
  321. if((exit_status = spectrack(dz))<0)
  322. return(exit_status);
  323. break;
  324. default:
  325. sprintf(errstr,"Unknown case in outer_pitch_loop()\n");
  326. return(PROGRAM_ERROR);
  327. }
  328. dz->flbufptr[0] += dz->wanted;
  329. }
  330. }
  331. if(samps_read<0) {
  332. sprintf(errstr,"Sound read error.\n");
  333. return(SYSTEM_ERROR);
  334. }
  335. if((exit_status = tidy_up_pitch_data(dz))<0)
  336. return(exit_status);
  337. if((exit_status = generate_tone(dz))<0)
  338. return(exit_status);
  339. dz->total_samps_written = 0;
  340. switch(dz->process) {
  341. case(PITCH): if(dz->mode == PICH_TO_BRK) thismode = 1; break;
  342. case(TRACK): if(dz->mode == TRK_TO_BRK) thismode = 1; break;
  343. default:
  344. sprintf(errstr,"Unknown mode in outer_pitch_loop().\n");
  345. return(PROGRAM_ERROR);
  346. }
  347. switch(thismode) {
  348. case(0):
  349. if((exit_status = write_samps_to_elsewhere(dz->other_file,dz->pitches,dz->wlength,dz))<0)
  350. return(exit_status);
  351. if((exit_status = write_pitch_outheader_from_analysis_inheader_to_second_outfile
  352. (dz->other_file,dz))<0)
  353. return(exit_status);
  354. break;
  355. case(1):
  356. /* MAY 2001 BRKPNT OUTPUT ELIMINATES PITCH ZEROS */
  357. if((exit_status = interpolate_pitch(dz->pitches,0,dz))<0)
  358. return(exit_status);
  359. if(dz->wlength == 1) {
  360. if((exit_status = convert_single_window_pch_or_transpos_data_to_brkpnttable
  361. (&brklen,dz->pitches,dz->frametime,PICH_PBRK,dz))<0)
  362. return(exit_status);
  363. } else {
  364. if((exit_status = convert_pch_or_transpos_data_to_brkpnttable
  365. (&brklen,dz->pitches,dz->frametime,PICH_PBRK,dz))<0)
  366. return(exit_status);
  367. }
  368. if((exit_status = write_brkfile(dz->fp,brklen,PICH_PBRK,dz))<0)
  369. return(exit_status);
  370. if(fclose(dz->fp)<0) {
  371. fprintf(stdout, "WARNING: Failed to close output brkpntfile.\n");
  372. fflush(stdout);
  373. }
  374. break;
  375. default:
  376. sprintf(errstr,"unknown output case in outer_pitch_loop()\n");
  377. return(PROGRAM_ERROR);
  378. }
  379. return(FINISHED);
  380. }
  381. /****************************** SPECPITCH *******************************
  382. *
  383. * (1) Ignore partials below low limit of pitch.
  384. * (2) If this channel data is louder than any existing piece of data in ring.
  385. * (Ring data is ordered loudness-wise)...
  386. * (3) If this freq is too close to an existing frequency..
  387. * (4) and if it is louder than that existing frequency data..
  388. * (5) Substitute in in the ring.
  389. * (6) Otherwise, (its a new frq) insert it into the ring.
  390. */
  391. int specpitch(dataptr dz)
  392. {
  393. int exit_status;
  394. int vc;
  395. chvptr here, there, *partials;
  396. float minamp;
  397. double loudest_partial_frq, nextloudest_partial_frq, lo_loud_partial, hi_loud_partial;
  398. if((partials = (chvptr *)malloc(MAXIMI * sizeof(chvptr)))==NULL) {
  399. sprintf(errstr,"INSUFFICIENT MEMORY for partials array.\n");
  400. return(MEMORY_ERROR);
  401. }
  402. if((exit_status = initialise_ring_vals(MAXIMI,-1.0,dz))<0)
  403. return(exit_status);
  404. if((exit_status = rectify_frqs(dz->flbufptr[0],dz))<0)
  405. return(exit_status);
  406. for(vc=0;vc<dz->wanted;vc+=2) {
  407. here = dz->ringhead;
  408. if(dz->flbufptr[0][FREQ] > dz->param[PICH_LOLM]) { /* 1 */
  409. do {
  410. if(dz->flbufptr[0][AMPP] > here->val) { /* 2 */
  411. if((exit_status = close_to_frq_already_in_ring(&there,(double)dz->flbufptr[0][FREQ],dz))<0)
  412. return(exit_status);
  413. if(exit_status==TRUE) {
  414. if(dz->flbufptr[0][AMPP] > there->val) { /* 4 */
  415. if((exit_status = substitute_in_ring(vc,here,there,dz))<0) /* 5 */
  416. return(exit_status);
  417. }
  418. } else { /* 6 */
  419. if((exit_status = insert_in_ring(vc,here,dz))<0)
  420. return(exit_status);
  421. }
  422. break;
  423. }
  424. } while((here = here->next)!=dz->ringhead);
  425. }
  426. }
  427. loudest_partial_frq = dz->flbufptr[0][dz->ringhead->loc + 1];
  428. nextloudest_partial_frq = dz->flbufptr[0][dz->ringhead->next->loc + 1];
  429. if(loudest_partial_frq < nextloudest_partial_frq) {
  430. lo_loud_partial = loudest_partial_frq;
  431. hi_loud_partial = nextloudest_partial_frq;
  432. } else {
  433. lo_loud_partial = nextloudest_partial_frq;
  434. hi_loud_partial = loudest_partial_frq;
  435. }
  436. if((exit_status = put_ring_frqs_in_ascending_order(&partials,&minamp,dz))<0)
  437. return(exit_status);
  438. if((exit_status = found_pitch(partials,lo_loud_partial,hi_loud_partial,minamp,dz))<0)
  439. return(exit_status);
  440. if(exit_status==TRUE && dz->param[PICH_PICH]>=MINPITCH)
  441. dz->pitches[dz->total_windows] = (float)dz->param[PICH_PICH];
  442. else
  443. dz->pitches[dz->total_windows] = (float)NOT_PITCH;
  444. return smooth_spurious_octave_leaps(dz->total_windows,minamp,dz);
  445. }
  446. /**************************** CLOSE_TO_FRQ_ALREADY_IN_RING *******************************/
  447. int close_to_frq_already_in_ring(chvptr *there,double frq1,dataptr dz)
  448. {
  449. #define EIGHT_OVER_SEVEN (1.142857143)
  450. double frq2, frqratio;
  451. *there = dz->ringhead;
  452. do {
  453. if((*there)->val > 0.0) {
  454. frq2 = dz->flbufptr[0][(*there)->loc + 1];
  455. if(frq1 > frq2)
  456. frqratio = frq1/frq2;
  457. else
  458. frqratio = frq2/frq1;
  459. if(frqratio < EIGHT_OVER_SEVEN)
  460. return(TRUE);
  461. }
  462. } while((*there = (*there)->next) != dz->ringhead);
  463. return(FALSE);
  464. }
  465. /******************************* SUBSITUTE_IN_RING **********************/
  466. int substitute_in_ring(int vc,chvptr here,chvptr there,dataptr dz)
  467. {
  468. chvptr spare, previous;
  469. if(here!=there) {
  470. if(there==dz->ringhead) {
  471. sprintf(errstr,"IMPOSSIBLE! in substitute_in_ring()\n");
  472. return(PROGRAM_ERROR);
  473. }
  474. spare = there;
  475. there->next->last = there->last; /* SPLICE REDUNDANT STRUCT FROM RING */
  476. there->last->next = there->next;
  477. previous = here->last;
  478. previous->next = spare; /* SPLICE ITS ADDRESS-SPACE BACK INTO RING */
  479. spare->last = previous; /* IMMEDIATELY BEFORE HERE */
  480. here->last = spare;
  481. spare->next = here;
  482. if(here==dz->ringhead) /* IF HERE IS RINGHEAD, MOVE RINGHEAD */
  483. dz->ringhead = spare;
  484. here = spare; /* POINT TO INSERT LOCATION */
  485. }
  486. here->val = dz->flbufptr[0][AMPP]; /* IF here==there */
  487. here->loc = vc; /* THIS WRITES OVER VAL IN EXISTING RING LOCATION */
  488. return(FINISHED);
  489. }
  490. /*************************** INSERT_IN_RING ***************************/
  491. int insert_in_ring(int vc, chvptr here, dataptr dz)
  492. {
  493. chvptr previous, newend, spare;
  494. if(here==dz->ringhead) {
  495. dz->ringhead = dz->ringhead->last;
  496. spare = dz->ringhead;
  497. } else {
  498. if(here==dz->ringhead->last)
  499. spare = here;
  500. else {
  501. spare = dz->ringhead->last;
  502. newend = dz->ringhead->last->last; /* cut ENDADR (spare) out of ring */
  503. dz->ringhead->last = newend;
  504. newend->next = dz->ringhead;
  505. previous = here->last;
  506. here->last = spare; /* reuse spare address at new loc by */
  507. spare->next = here; /* inserting it back into ring before HERE */
  508. previous->next = spare;
  509. spare->last = previous;
  510. }
  511. }
  512. spare->val = dz->flbufptr[0][vc]; /* Store new val in spare ring location */
  513. spare->loc = vc;
  514. return(FINISHED);
  515. }
  516. /************************** PUT_RING_FRQS_IN_ASCENDING_ORDER **********************/
  517. int put_ring_frqs_in_ascending_order(chvptr **partials,float *minamp,dataptr dz)
  518. {
  519. int k;
  520. chvptr start, ggot, here = dz->ringhead;
  521. float minpitch;
  522. *minamp = (float)MAXFLOAT;
  523. for(k=0;k<MAXIMI;k++) {
  524. if((*minamp = min(dz->flbufptr[0][here->loc],*minamp))>=(float)MAXFLOAT) {
  525. sprintf(errstr,"Problem with amplitude out of range: put_ring_frqs_in_ascending_order()\n");
  526. return(PROGRAM_ERROR);
  527. }
  528. (here->loc)++; /* CHANGE RING TO POINT TO FRQS, not AMPS */
  529. here->val = dz->flbufptr[0][here->loc];
  530. here = here->next;
  531. }
  532. here = dz->ringhead;
  533. minpitch = dz->flbufptr[0][here->loc];
  534. for(k=1;k<MAXIMI;k++) {
  535. start = ggot = here;
  536. while((here = here->next)!=start) { /* Find lowest frq */
  537. if(dz->flbufptr[0][here->loc] < minpitch) {
  538. minpitch = dz->flbufptr[0][here->loc];
  539. ggot = here;
  540. }
  541. }
  542. (*partials)[k-1] = ggot; /* Save its address */
  543. here = ggot->next; /* Move to next ring site */
  544. minpitch = dz->flbufptr[0][here->loc]; /* Preset minfrq to val there */
  545. ggot->last->next = here; /* Unlink ringsite ggot */
  546. here->last = ggot->last;
  547. }
  548. (*partials)[k-1] = here; /* Remaining ringsite is maximum */
  549. here = dz->ringhead = (*partials)[0]; /* Reconstruct ring */
  550. for(k=1;k<MAXIMI;k++) {
  551. here->next = (*partials)[k];
  552. (*partials)[k]->last = here;
  553. here = here->next;
  554. }
  555. here->next = dz->ringhead; /* Close up ring */
  556. dz->ringhead->last = here;
  557. return(FINISHED);
  558. }
  559. /****************************** FIND_PITCH **************************/
  560. int found_pitch(chvptr *partials,double lo_loud_partial,double hi_loud_partial,float minamp,dataptr dz)
  561. {
  562. switch(dz->vflag[PICH_ALTERNATIVE_METHOD]) {
  563. case(FALSE): return(found_pitch_1(partials,lo_loud_partial,hi_loud_partial,minamp,dz));
  564. case(TRUE): return(found_pitch_2(partials,dz));
  565. default:
  566. sprintf(errstr,"Unknown case in found_pitch()\n");
  567. return(PROGRAM_ERROR);
  568. }
  569. }
  570. /****************************** FIND_PITCH_1 **************************/
  571. #define MAXIMUM_PARTIAL (64)
  572. int found_pitch_1(chvptr *partials,double lo_loud_partial,double hi_loud_partial,float minamp,dataptr dz)
  573. {
  574. int n, m, k, maximi_less_one = MAXIMUM_PARTIAL - 1, endd = 0;
  575. double whole_number_ratio, comparison_frq;
  576. for(n=1;n<maximi_less_one;n++) {
  577. for(m=n+1;m<MAXIMUM_PARTIAL;m++) { /* NOV 7 */
  578. whole_number_ratio = (double)m/(double)n;
  579. comparison_frq = lo_loud_partial * whole_number_ratio;
  580. if(equivalent_pitches(comparison_frq,hi_loud_partial,dz))
  581. endd = (MAXIMUM_PARTIAL/m) * n; /* explanation at foot of file */
  582. else if(comparison_frq > hi_loud_partial)
  583. break;
  584. for(k=n;k<=endd;k+=n) {
  585. dz->param[PICH_PICH] = lo_loud_partial/(double)k;
  586. if(dz->param[PICH_PICH]>dz->param[PICH_HILM])
  587. continue;
  588. if(dz->param[PICH_PICH]<dz->param[PICH_LOLM])
  589. break;
  590. if(is_peak_at(dz->param[PICH_PICH],0,minamp,dz)){
  591. if(dz->iparam[PICH_MATCH] <= 2)
  592. return TRUE;
  593. else if(enough_partials_are_harmonics(partials,dz))
  594. return TRUE;
  595. }
  596. }
  597. }
  598. }
  599. return(FALSE);
  600. }
  601. /********************** FIND_PITCH_2 *****************************/
  602. int found_pitch_2(chvptr *partials,dataptr dz)
  603. {
  604. int m, n, k, good_match;
  605. int top_of_test = MAXIMI - dz->iparam[PICH_MATCH] + 1;
  606. double resolved_pitch, prevpitch,pitchdiff = 0.0;
  607. int diffcount = 0;
  608. for(n=0;n<top_of_test;n++) {
  609. for(m=1;m<=MAXHARM;m++) {
  610. dz->param[PICH_PICH] = (partials[n]->val)/(double)m;
  611. if(dz->param[PICH_PICH] > dz->param[PICH_HILM])
  612. continue;
  613. if(dz->param[PICH_PICH] < dz->param[PICH_LOLM])
  614. break;
  615. good_match = 1;
  616. prevpitch = dz->param[PICH_PICH];
  617. if(dz->iparam[PICH_MATCH] > 1) {
  618. for(k=n+1;k<MAXIMI;k++) {
  619. if(is_a_harmonic((double)(partials[k]->val),dz->param[PICH_PICH],dz)) {
  620. pitchdiff += (double)(partials[k]->val - prevpitch);
  621. prevpitch = (double)(partials[k]->val);
  622. diffcount++;
  623. if(++good_match >= dz->iparam[PICH_MATCH]) {
  624. resolved_pitch = pitchdiff / (double)diffcount;
  625. if(equivalent_pitches(resolved_pitch,dz->param[PICH_PICH],dz)){
  626. partials[0]->val = (float) resolved_pitch;
  627. dz->param[PICH_PICH] = resolved_pitch;
  628. }
  629. return TRUE;
  630. }
  631. }
  632. }
  633. }
  634. }
  635. }
  636. return(FALSE);
  637. }
  638. /************************ SMOOTH_SPURIOUS_OCTAVE_LEAPS ***************************/
  639. int smooth_spurious_octave_leaps(int pitchno,float minamp,dataptr dz)
  640. {
  641. #define ALMOST_TWO (1.75)
  642. double thispitch = dz->pitches[pitchno];
  643. double startpitch, lastpitch;
  644. int k = 0;
  645. if(pitchno<=0)
  646. return(FINISHED);
  647. lastpitch = dz->pitches[pitchno-1];
  648. if(lastpitch > dz->param[PICH_LOLM] && thispitch > dz->param[PICH_LOLM]) { /* OCTAVE ADJ HERE */
  649. if(thispitch > lastpitch) { /* OCTAVE ADJ FORWARDS */
  650. startpitch = thispitch;
  651. while(thispitch/lastpitch > ALMOST_TWO)
  652. thispitch /= 2.0;
  653. if(thispitch!=startpitch) {
  654. if(thispitch < dz->param[PICH_LOLM])
  655. return(FINISHED);
  656. if(is_peak_at(thispitch,0L,minamp,dz))
  657. dz->pitches[pitchno] = (float)thispitch;
  658. else
  659. dz->pitches[pitchno] = (float)startpitch;
  660. }
  661. return(FINISHED);
  662. } else {
  663. while(pitchno>=1) { /* OCTAVE ADJ BCKWARDS */
  664. k++;
  665. if((thispitch = dz->pitches[pitchno--])<dz->param[PICH_LOLM])
  666. return(FINISHED);
  667. if((lastpitch = dz->pitches[pitchno])<dz->param[PICH_LOLM])
  668. return(FINISHED);
  669. startpitch = lastpitch;
  670. while(lastpitch/thispitch > ALMOST_TWO)
  671. lastpitch /= 2.0;
  672. if(lastpitch!=startpitch) {
  673. if(lastpitch < dz->param[PICH_LOLM])
  674. return(FINISHED);
  675. if(is_peak_at(lastpitch,k,minamp,dz))
  676. dz->pitches[pitchno] = (float)lastpitch;
  677. else
  678. dz->pitches[pitchno] = (float)startpitch;
  679. }
  680. }
  681. }
  682. }
  683. return(FINISHED);
  684. }
  685. /**************************** EQUIVALENT_PITCHES *************************/
  686. int equivalent_pitches(double frq1, double frq2, dataptr dz)
  687. {
  688. double ratio;
  689. int iratio;
  690. double intvl;
  691. ratio = frq1/frq2;
  692. iratio = round(ratio);
  693. if(iratio!=1)
  694. return(FALSE);
  695. if(ratio > iratio)
  696. intvl = ratio/(double)iratio;
  697. else
  698. intvl = (double)iratio/ratio;
  699. if(intvl > dz->param[PICH_RNGE])
  700. return FALSE;
  701. return TRUE;
  702. }
  703. /*************************** IS_PEAK_AT ***************************/
  704. #define PEAK_LIMIT (.05)
  705. int is_peak_at(double frq,int window_offset,float minamp,dataptr dz)
  706. {
  707. float *thisbuf;
  708. int cc, vc, searchtop, searchbot;
  709. if(window_offset) { /* BAKTRAK ALONG BIGBUF, IF NESS */
  710. thisbuf = dz->flbufptr[0] - (window_offset * dz->wanted);
  711. if((int)thisbuf < 0 || thisbuf < dz->bigfbuf || thisbuf >= dz->flbufptr[1])
  712. return(FALSE);
  713. } else
  714. thisbuf = dz->flbufptr[0];
  715. cc = (int)((frq + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */
  716. searchtop = min(dz->clength,cc + CHANSCAN + 1);
  717. searchbot = max(0,cc - CHANSCAN);
  718. for(cc = searchbot ,vc = searchbot*2; cc < searchtop; cc++, vc += 2) {
  719. if(!equivalent_pitches((double)thisbuf[vc+1],frq,dz)) {
  720. continue;
  721. }
  722. if(thisbuf[vc] < minamp * PEAK_LIMIT)
  723. continue;
  724. if(local_peak(cc,frq,thisbuf,dz))
  725. return TRUE;
  726. }
  727. return FALSE;
  728. }
  729. /**************************** ENOUGH_PARTIALS_ARE_HARMONICS *************************/
  730. int enough_partials_are_harmonics(chvptr *partials,dataptr dz)
  731. {
  732. int n, good_match = 0;
  733. double thisfrq;
  734. for(n=0;n<MAXIMI;n++) {
  735. if((thisfrq = dz->flbufptr[0][partials[n]->loc]) < dz->param[PICH_PICH])
  736. continue;
  737. if(is_a_harmonic(thisfrq,dz->param[PICH_PICH],dz)){
  738. if(++good_match >= dz->iparam[PICH_MATCH])
  739. return TRUE;
  740. }
  741. }
  742. return FALSE;
  743. }
  744. /**************************** IS_A_HARMONIC *************************/
  745. int is_a_harmonic(double frq1,double frq2,dataptr dz)
  746. {
  747. double ratio = frq1/frq2;
  748. int iratio = round(ratio);
  749. double intvl;
  750. ratio = frq1/frq2;
  751. iratio = round(ratio);
  752. if(ratio > iratio)
  753. intvl = ratio/(double)iratio;
  754. else
  755. intvl = (double)iratio/ratio;
  756. if(intvl > dz->param[PICH_RNGE])
  757. return(FALSE);
  758. return(TRUE);
  759. }
  760. /***************************** SPECTRACK *********************************/
  761. int spectrack(dataptr dz)
  762. {
  763. int exit_status;
  764. double thisfrq = dz->param[TRAK_PICH], frqtop, frqbot, maxamp;
  765. double outfrq = 0.0;
  766. int n = 0, vc = 0, passed_limit = 0, maxloc;
  767. while((thisfrq = dz->param[TRAK_PICH] * (double)++n) < dz->param[TRAK_HILM]) {
  768. frqtop = thisfrq * dz->param[TRAK_RNGE];
  769. frqbot = thisfrq / dz->param[TRAK_RNGE];
  770. if((exit_status = rectify_frqs(dz->flbufptr[0],dz))<0)
  771. return(exit_status);
  772. while(dz->flbufptr[0][FREQ] < frqbot) { /* JUMP OVER CHANNELS */
  773. if((vc+=2) >=dz->wanted) {
  774. outfrq = -1.0;
  775. passed_limit = 1;
  776. break;
  777. }
  778. }
  779. if(passed_limit) /* IF GONE PAST LIMIT */
  780. break; /* BREAK OUT OF LOOP */
  781. if(dz->flbufptr[0][FREQ]>frqtop) { /* IF OUTSIDE RANGE */
  782. outfrq = -1.0; /* BREAK OUT OF LOOP */
  783. break;
  784. }
  785. maxamp = dz->flbufptr[0][AMPP]; /* SET MAXAMP TO 1ST IN-RANGE CH */
  786. maxloc = vc; /* NOTE NO. OF CH THUS MARKED */
  787. while((vc+=2) < dz->wanted) {
  788. if(dz->flbufptr[0][FREQ]>frqtop) /* IF BEYOND CURRENT RANGE, STOP */
  789. break;
  790. if(dz->flbufptr[0][AMPP]>maxamp) { /* IF LOUDER THAN MAX, RESET MAX */
  791. maxamp = dz->flbufptr[0][AMPP]; /* AND RESET MAXAMP CHANNEL NO. */
  792. maxloc = vc;
  793. }
  794. }
  795. outfrq = dz->flbufptr[0][maxloc+1];
  796. }
  797. if(outfrq>MINPITCH) /* If pitch has been found */
  798. dz->param[TRAK_PICH] = outfrq; /* reset goal pitch to this */
  799. dz->pitches[dz->total_windows] = (float)outfrq;
  800. return(FINISHED);
  801. }
  802. /**************************** OUTER_PICHPICH_LOOP *********************/
  803. int outer_pichpich_loop(dataptr dz)
  804. {
  805. int exit_status, valid_pitch_data = FALSE;
  806. int final_length_in_windows = dz->wlength, n;
  807. double lastmidi;
  808. if(dz->is_transpos) {
  809. if((dz->transpos = (float *)malloc(dz->wlength * sizeof(float)))==NULL) {
  810. sprintf(errstr,"INSUFFICIENT MEMORY for transpositions array.\n");
  811. return(MEMORY_ERROR);
  812. }
  813. for(n=0;n<dz->wlength;n++)
  814. dz->transpos[n] = 1.0f; /* DEFAULT: no transposition */
  815. }
  816. for(n=0;n<dz->wlength;n++) {
  817. if(dz->pitches[n] > FLTERR) {
  818. valid_pitch_data = 1;
  819. break;
  820. }
  821. }
  822. if(!valid_pitch_data) {
  823. sprintf(errstr,"No valid pitches found in input data.\n");
  824. return(DATA_ERROR);
  825. }
  826. switch(dz->process) {
  827. case(P_APPROX):
  828. if((exit_status = specpapprox(&final_length_in_windows,&lastmidi,dz))<0)
  829. return(exit_status);
  830. if((exit_status = trap_junk(final_length_in_windows,dz))<0)
  831. return(exit_status);
  832. return write_remaining_pitch_or_transpos_data(final_length_in_windows,dz);
  833. case(P_CUT):
  834. if((exit_status = specpcut(&final_length_in_windows,dz))<0)
  835. return(exit_status);
  836. return write_remaining_pitch_or_transpos_data(final_length_in_windows,dz);
  837. case(P_EXAG):
  838. if((exit_status = specpexag(dz))<0)
  839. return(exit_status);
  840. break;
  841. case(P_INVERT):
  842. if((exit_status = specpinvert(dz))<0)
  843. return(exit_status);
  844. break;
  845. case(P_QUANTISE):
  846. if((exit_status = specpquantise(dz))<0)
  847. return(exit_status);
  848. break;
  849. case(P_RANDOMISE):
  850. if((exit_status = specprand(dz))<0)
  851. return(exit_status);
  852. break;
  853. case(P_SMOOTH):
  854. if((exit_status = specpsmooth(dz))<0)
  855. return(exit_status);
  856. break;
  857. case(P_TRANSPOSE):
  858. if((exit_status = specptranspose(dz))<0)
  859. return(exit_status);
  860. break;
  861. case(P_VIBRATO):
  862. if((exit_status = specpvib(dz))<0)
  863. return(exit_status);
  864. break;
  865. case(P_SYNTH):
  866. return generate_tone(dz);
  867. break;
  868. case(P_VOWELS):
  869. return generate_vowels(dz);
  870. break;
  871. case(P_INSERT):
  872. if((exit_status = pitch_insert(0,dz)) < 0)
  873. return(exit_status);
  874. return write_pitch_or_transpos_data(final_length_in_windows,dz);
  875. break;
  876. case(P_SINSERT):
  877. if((exit_status = pitch_insert(1,dz)) < 0)
  878. return(exit_status);
  879. return write_pitch_or_transpos_data(final_length_in_windows,dz);
  880. break;
  881. case(P_PTOSIL):
  882. if((exit_status = pitch_to_silence(dz)) < 0)
  883. return(exit_status);
  884. return write_pitch_or_transpos_data(final_length_in_windows,dz);
  885. break;
  886. case(P_NTOSIL):
  887. if((exit_status = unpitch_to_silence(dz)) < 0)
  888. return(exit_status);
  889. return write_pitch_or_transpos_data(final_length_in_windows,dz);
  890. break;
  891. case(P_INTERP):
  892. if((exit_status = remove_pitch_zeros(dz)) < 0)
  893. return(exit_status);
  894. return write_pitch_or_transpos_data(dz->wlength,dz);
  895. break;
  896. default:
  897. sprintf(errstr,"Unknown process in outer_pichpich_loop()\n");
  898. return(PROGRAM_ERROR);
  899. }
  900. if((exit_status = trap_junk(final_length_in_windows,dz))<0)
  901. return(exit_status);
  902. return write_pitch_or_transpos_data(final_length_in_windows,dz);
  903. }
  904. /************************** SPECPAPPROX ************************/
  905. int specpapprox(int *newlength_of_data,double *lastmidi,dataptr dz)
  906. {
  907. int exit_status;
  908. int avcnt;
  909. int n = 0, diff;
  910. int is_firstime = TRUE;
  911. int lastpos = 0;
  912. *newlength_of_data = dz->wlength;
  913. initrand48();
  914. if((exit_status = get_pitchapprox_averages(&avcnt,dz))<0)
  915. return(exit_status);
  916. if((dz->iparray[PA_CHANGE] = (int *)malloc(avcnt * sizeof(int)))==NULL) {
  917. sprintf(errstr,"INSUFFICIENT MEMORY for pitch approximation array.\n");
  918. return(MEMORY_ERROR);
  919. }
  920. if((exit_status = get_statechanges(avcnt,PA_SRANG,PA_AVPICH,PA_CHANGE,SEMITONE_INTERVAL,SEMITONE_DOWN,IS_FRQ,dz))<0)
  921. return(exit_status);
  922. while(dz->parray[PA_AVPICH][n]<0.0) {
  923. if(++n>=avcnt) {
  924. sprintf(errstr,"No valid pitch-average data found.\n");
  925. return(DATA_ERROR); /* ??? */
  926. }
  927. }
  928. dz->iparray[PA_CHANGE][n] = 1;
  929. for(;n<avcnt;n++) {
  930. if(dz->iparray[PA_CHANGE][n]) {
  931. if((exit_status = approx_func1(newlength_of_data,&is_firstime,lastmidi,&lastpos,n,dz))<0)
  932. return(exit_status);
  933. if(exit_status==FINISHED)
  934. break;
  935. }
  936. }
  937. if((diff = (dz->wlength-1) - lastpos) > 0
  938. && (exit_status = approx_func2(newlength_of_data,*lastmidi,lastpos,avcnt,dz))<0)
  939. return(exit_status);
  940. return(FINISHED);
  941. }
  942. /***************************** SPECPCUT ***************************/
  943. int specpcut(int *final_length_in_windows,dataptr dz)
  944. {
  945. int m, n;
  946. int startcut = 0;
  947. int endcut = dz->wlength;
  948. if(dz->mode != PCUT_START_ONLY) /* is_endtime */
  949. endcut = round(dz->param[PC_END]/dz->frametime);
  950. if(dz->mode != PCUT_END_ONLY) /* is_starttime */
  951. startcut = round(dz->param[PC_STT]/dz->frametime);
  952. for(m = 0, n = startcut; n < endcut; n++, m++)
  953. dz->pitches[m] = dz->pitches[n];
  954. *final_length_in_windows = endcut - startcut;
  955. return(FINISHED);
  956. }
  957. /************************************* SPECPEXAG ******************************/
  958. int specpexag(dataptr dz)
  959. {
  960. int exit_status;
  961. int n;
  962. double thismidi, maxmidi, minmidi, variance, thispich;
  963. double maxpitch = FLTERR, minpitch = dz->nyquist, meanpich, maxint, minint;
  964. dz->time = 0.0f;
  965. if((exit_status = get_max_and_min_pitches(&maxpitch,&minpitch,dz))<0)
  966. return(exit_status);
  967. if((exit_status = hztomidi(&maxmidi,maxpitch))<0)
  968. return(exit_status);
  969. if((exit_status = hztomidi(&minmidi,minpitch))<0)
  970. return(exit_status);
  971. for(n=0;n<dz->wlength;n++) {
  972. if(dz->pitches[n]<MINPITCH)
  973. continue;
  974. if((exit_status = read_values_from_all_existing_brktables((double)dz->time,dz))<0)
  975. return(exit_status);
  976. meanpich = miditohz(dz->param[PEX_MEAN]);
  977. thispich = dz->pitches[n];
  978. /* contour variable specified */
  979. if(dz->mode != RANGE_ONLY_TO_P && dz->mode != RANGE_ONLY_TO_T) {
  980. if((exit_status = hztomidi(&thismidi,thispich))<0)
  981. return(exit_status);
  982. maxint = maxmidi - dz->param[PEX_MEAN];
  983. minint = dz->param[PEX_MEAN] - minmidi;
  984. if(thismidi >= dz->param[PEX_MEAN])
  985. variance = ((thismidi - dz->param[PEX_MEAN])/12.0)/maxint;
  986. else
  987. variance = ((dz->param[PEX_MEAN] - thismidi)/12.0)/minint;
  988. if(!flteq(variance,0.0))
  989. variance = pow(variance,dz->param[PEX_CNTR]);
  990. if(thismidi>=dz->param[PEX_MEAN])
  991. thispich = (float)(pow(maxpitch,variance) * pow(meanpich,(1.0-variance)));
  992. else
  993. thispich = (float)(pow(minpitch,variance) * pow(meanpich,(1.0-variance)));
  994. }
  995. if(dz->mode != CONTOUR_ONLY_TO_P && dz->mode != CONTOUR_ONLY_TO_T) {
  996. /* range variable specified */
  997. if((exit_status = hztomidi(&thismidi,thispich))<0)
  998. return(exit_status);
  999. thismidi = dz->param[PEX_MEAN] + ((thismidi - dz->param[PEX_MEAN])
  1000. * dz->param[PEX_RANG]);
  1001. thispich = (float)miditohz(thismidi);
  1002. }
  1003. if(dz->is_transpos) { /* transpos output */
  1004. dz->transpos[n] = (float)(thispich/dz->pitches[n]);
  1005. check_transpos(&(dz->transpos[n]),dz);
  1006. } else {
  1007. dz->pitches[n] = (float)thispich;
  1008. check_pitch(&(dz->pitches[n]),dz);
  1009. }
  1010. dz->time = (float)(dz->time + dz->frametime);
  1011. }
  1012. return(FINISHED);
  1013. }
  1014. /****************************** SPECPFIX ********************************/
  1015. int specpfix(dataptr dz)
  1016. {
  1017. int exit_status;
  1018. if(dz->iparam[PF_ISCUT] && (exit_status = do_pitch_cut(dz))<0)
  1019. return(exit_status);
  1020. if(dz->iparam[PF_ISFILTER] && (exit_status = do_pitch_filter(dz))<0)
  1021. return(exit_status);
  1022. if(dz->vflag[PF_IS_SMOOTH] && (exit_status = do_pitch_smoothing(dz))<0)
  1023. return(exit_status);
  1024. if(dz->vflag[PF_IS_SMARK])
  1025. dz->pitches[0] = (float)dz->param[PF_SMARK];
  1026. if(dz->vflag[PF_IS_EMARK])
  1027. dz->pitches[dz->wlength-1] = (float)dz->param[PF_EMARK];
  1028. if(dz->vflag[PF_INTERP] && (exit_status = interpolate_pitch(dz->pitches,1,dz))<0)
  1029. return(exit_status);
  1030. return write_exact_samps(dz->pitches,dz->wlength,dz);
  1031. }
  1032. /************************** SPECPINVERT ************************/
  1033. int specpinvert(dataptr dz)
  1034. {
  1035. int exit_status;
  1036. int n;
  1037. double midimean = 0.0, thismidi, thisint;
  1038. dz->time = 0.0f;
  1039. if(!dz->vflag[PI_IS_MEAN]) {
  1040. if((exit_status = get_midimean(&midimean,dz))<0)
  1041. return(exit_status);
  1042. } else
  1043. midimean = dz->param[PI_MEAN];
  1044. for(n=0;n<dz->wlength;n++) {
  1045. if(dz->pitches[n]<MINPITCH)
  1046. continue;
  1047. if((exit_status = read_values_from_all_existing_brktables((double)dz->time,dz))<0)
  1048. return(exit_status);
  1049. if((exit_status = hztomidi(&thismidi,dz->pitches[n]))<0)
  1050. return(exit_status);
  1051. if(dz->is_mapping) {
  1052. if((exit_status = interval_mapping(&thisint,thismidi - midimean,dz))<0)
  1053. return(exit_status);
  1054. thismidi = max(dz->param[PI_BOT],min(dz->param[PI_TOP],midimean + thisint));
  1055. } else
  1056. thismidi = min(dz->param[PI_TOP],max(dz->param[PI_BOT],((2.0 * midimean) - thismidi)));
  1057. if(dz->is_transpos) {
  1058. dz->transpos[n] = (float)(miditohz(thismidi)/dz->pitches[n]);
  1059. check_transpos(&(dz->transpos[n]),dz);
  1060. } else {
  1061. dz->pitches[n] = (float)miditohz(thismidi);
  1062. check_pitch(&(dz->pitches[n]),dz);
  1063. }
  1064. dz->time = (float)(dz->time + dz->frametime);
  1065. }
  1066. return(FINISHED);
  1067. }
  1068. /************************************** SPECPQUANTISE **************************/
  1069. int specpquantise(dataptr dz)
  1070. {
  1071. int exit_status;
  1072. int n;
  1073. int got;
  1074. double *p, thismidi;
  1075. double *pend = dz->parray[PQ_QSET] + dz->itemcnt;
  1076. for(n=0;n<dz->wlength;n++) {
  1077. if(dz->pitches[n]<MINPITCH)
  1078. continue;
  1079. got = 0;
  1080. p = dz->parray[PQ_QSET];
  1081. if((exit_status = hztomidi(&thismidi,dz->pitches[n]))<0)
  1082. return(exit_status);
  1083. if(*p >= thismidi) {
  1084. if((exit_status = set_pval(*p,n,dz))<0)
  1085. return(exit_status);
  1086. continue;
  1087. }
  1088. while(*p < thismidi) {
  1089. if(++p >= pend) {
  1090. p--;
  1091. if((exit_status = set_pval(*p,n,dz))<0)
  1092. return(exit_status);
  1093. got = 1;
  1094. break;
  1095. }
  1096. }
  1097. if(got)
  1098. continue;
  1099. if((*p - thismidi) > (thismidi - *(p-1))) {
  1100. if((exit_status = set_pval(*(p-1),n,dz))<0)
  1101. return(exit_status);
  1102. } else {
  1103. if((exit_status = set_pval(*p,n,dz))<0)
  1104. return(exit_status);
  1105. }
  1106. }
  1107. return(FINISHED);
  1108. }
  1109. /***************************************** SPECPRAND *********************/
  1110. int specprand(dataptr dz)
  1111. {
  1112. int exit_status;
  1113. int n = 0, lastn, m, thiswstep, diff, z;
  1114. double thisintv, ttime = 0.0, lastmidi, thismidi, mididiff, midistep;
  1115. initrand48();
  1116. while(dz->pitches[n]<MINPITCH) {
  1117. if(++n>=dz->wlength) {
  1118. sprintf(errstr,"No valid pitchdata found in pitch file.\n");
  1119. return(DATA_ERROR);
  1120. }
  1121. }
  1122. if((exit_status = hztomidi(&lastmidi,dz->pitches[n]))<0)
  1123. return(exit_status);
  1124. ttime = dz->frametime * (double)n;
  1125. if((exit_status = read_values_from_all_existing_brktables(ttime,dz))<0)
  1126. return(exit_status);
  1127. if((exit_status = get_rand_interval(&thisintv,dz))<0)
  1128. return(exit_status);
  1129. lastmidi += thisintv;
  1130. if((exit_status = set_pval(lastmidi,n,dz))<0)
  1131. return(exit_status);
  1132. lastn = n;
  1133. do {
  1134. thiswstep = round(max(dz->frametime,drand48() * dz->param[PR_TSTEP])/dz->frametime);
  1135. if((n += thiswstep) >= dz->wlength) {
  1136. sprintf(errstr,"Too much unpitched data in file to proceed this time. But try again.\n");
  1137. return(DATA_ERROR);
  1138. }
  1139. ttime = dz->frametime * (double)n;
  1140. if(dz->brksize[PR_TSTEP]) {
  1141. if((exit_status = read_value_from_brktable(ttime,PR_TSTEP,dz))<0)
  1142. return(exit_status);
  1143. }
  1144. } while(dz->pitches[n]<MINPITCH);
  1145. while(n<dz->wlength) {
  1146. if(dz->brksize[PR_MXINT]) {
  1147. if((exit_status = read_value_from_brktable(ttime,PR_MXINT,dz))<0)
  1148. return(exit_status);
  1149. }
  1150. if((exit_status = get_rand_interval(&thisintv,dz))<0)
  1151. return(exit_status);
  1152. if((exit_status = hztomidi(&thismidi,dz->pitches[n]))<0)
  1153. return(exit_status);
  1154. thismidi += thisintv;
  1155. mididiff = thismidi - lastmidi;
  1156. diff = n - lastn;
  1157. midistep = mididiff/(double)diff;
  1158. for(m = lastn+1;m<=n;m++) { /* Interp pitch between randomised points */
  1159. if(dz->pitches[m] < MINPITCH)
  1160. continue;
  1161. lastmidi += midistep;
  1162. if((exit_status = set_pval(lastmidi,m,dz))<0)
  1163. return(exit_status);
  1164. }
  1165. lastmidi = thismidi;
  1166. lastn = n;
  1167. do {
  1168. if(dz->brksize[PR_TSTEP]) {
  1169. if((exit_status = read_value_from_brktable(ttime,PR_TSTEP,dz))<0)
  1170. return(exit_status);
  1171. }
  1172. thiswstep = round(max(dz->frametime,drand48() * dz->param[PR_TSTEP])/dz->frametime);
  1173. if((n+=thiswstep) > dz->wlength)
  1174. break;
  1175. ttime = dz->frametime * (double)n;
  1176. } while(dz->pitches[n]<MINPITCH);
  1177. }
  1178. if(lastn < dz->wlength-1) {
  1179. z = dz->wlength - 1;
  1180. while(dz->pitches[z]<MINPITCH) {
  1181. if(--z<=lastn)
  1182. return(FINISHED);
  1183. }
  1184. n = z;
  1185. thisintv = ((drand48() * 2.0) - 1.0) * dz->param[PR_MXINT];
  1186. if((exit_status = hztomidi(&thismidi,dz->pitches[n]))<0)
  1187. return(exit_status);
  1188. thismidi += thisintv;
  1189. mididiff = thismidi - lastmidi;
  1190. if((diff = n - lastn)<2)
  1191. return(FINISHED);
  1192. midistep = mididiff/(double)diff;
  1193. for(m = lastn+1;m<=n;m++) {
  1194. if(dz->pitches[n]<MINPITCH)
  1195. continue;
  1196. lastmidi += midistep;
  1197. if((exit_status = set_pval(lastmidi,m,dz))<0)
  1198. return(exit_status);
  1199. }
  1200. }
  1201. return(FINISHED);
  1202. }
  1203. /*************************************** SPECPSMOOTH ***********************************/
  1204. int specpsmooth(dataptr dz)
  1205. {
  1206. int exit_status;
  1207. double ttime = 0.0, maxpitch = FLTERR, minpitch = dz->nyquist,
  1208. maxmidi, minmidi, lastmidi;
  1209. double meanpich, maxint, minint, startmidi, endmidi, thismidi, mdiff, step;
  1210. int lastmaxpos = 0, n=0, m, z, interpfact, lastn;
  1211. if((exit_status = get_max_and_min_pitches(&maxpitch,&minpitch,dz))<0)
  1212. return(exit_status);
  1213. if((exit_status = hztomidi(&maxmidi,maxpitch))<0)
  1214. return(exit_status);
  1215. if((exit_status = hztomidi(&minmidi,minpitch))<0)
  1216. return(exit_status);
  1217. n = 0;
  1218. while(dz->pitches[n]<MINPITCH) {
  1219. if(++n >= dz->wlength) {
  1220. sprintf(errstr,"No valid data in pitchfile\n");
  1221. return(DATA_ERROR);
  1222. }
  1223. }
  1224. if(dz->is_transpos)
  1225. dz->transpos[n] = 1.0f;
  1226. if((exit_status = hztomidi(&lastmidi,dz->pitches[n]))<0)
  1227. return(exit_status);
  1228. ttime = (double)n * dz->frametime;
  1229. if((exit_status = read_values_from_all_existing_brktables(ttime,dz))<0)
  1230. return(exit_status);
  1231. interpfact = round(dz->param[PS_TFRAME]/dz->frametime);
  1232. lastn = n;
  1233. do {
  1234. if((n += interpfact) >=dz->wlength) {
  1235. sprintf(errstr,"Too much unpitched data in file: cannot proceed. Try different interpfact(s).\n");
  1236. return(DATA_ERROR);
  1237. }
  1238. ttime = (double)n * dz->frametime;
  1239. if(dz->brksize[PS_TFRAME]) {
  1240. if((exit_status = read_value_from_brktable(ttime,PS_TFRAME,dz))<0)
  1241. return(exit_status);
  1242. interpfact = round(dz->param[PS_TFRAME]/dz->frametime);
  1243. }
  1244. } while(dz->pitches[n]<MINPITCH);
  1245. if(dz->vflag[PS_MEANP]) {
  1246. meanpich = miditohz(dz->param[PS_MEAN]);
  1247. maxint = maxmidi - dz->param[PS_MEAN];
  1248. minint = dz->param[PS_MEAN] - minmidi;
  1249. while(n<dz->wlength) {
  1250. if((exit_status = peak_interp(n,lastn,&lastmaxpos,meanpich,minint,maxint,&lastmidi,dz))<0)
  1251. return(exit_status);
  1252. if(dz->brksize[PS_TFRAME]) {
  1253. if((exit_status = read_value_from_brktable(ttime,PS_TFRAME,dz))<0)
  1254. return(exit_status);
  1255. interpfact = round(dz->param[PS_TFRAME]/dz->frametime);
  1256. }
  1257. if(dz->brksize[PS_MEAN]) {
  1258. if((exit_status = read_value_from_brktable(ttime,PS_MEAN,dz))<0)
  1259. return(exit_status);
  1260. meanpich = miditohz(dz->param[PS_MEAN]);
  1261. maxint = maxmidi - dz->param[PS_MEAN];
  1262. minint = dz->param[PS_MEAN] - minmidi;
  1263. }
  1264. lastn = n;
  1265. do{
  1266. if((n += interpfact) >= dz->wlength)
  1267. break;
  1268. ttime = (double)n * dz->frametime;
  1269. if(dz->brksize[PS_TFRAME]) {
  1270. if((exit_status = read_value_from_brktable(ttime,PS_TFRAME,dz))<0)
  1271. return(exit_status);
  1272. interpfact = round(dz->param[PS_TFRAME]/dz->frametime);
  1273. }
  1274. } while(dz->pitches[n]<MINPITCH);
  1275. }
  1276. n = lastmaxpos;
  1277. } else {
  1278. while(n<dz->wlength) {
  1279. z = n - lastn;
  1280. if((exit_status = hztomidi(&startmidi,dz->pitches[lastn]))<0)
  1281. return(exit_status);
  1282. if((exit_status = hztomidi(&endmidi,dz->pitches[n]))<0)
  1283. return(exit_status);
  1284. mdiff = endmidi - startmidi;
  1285. step = mdiff/(double)z;
  1286. for(m=1;m<=z;m++) {
  1287. if(dz->pitches[m+lastn]<MINPITCH)
  1288. continue;
  1289. thismidi = startmidi + (step * (double)m);
  1290. if((exit_status = set_pval(thismidi,m+lastn,dz))<0)
  1291. return(exit_status);
  1292. }
  1293. lastn = n;
  1294. do{
  1295. if((n += interpfact) >=dz->wlength)
  1296. break;
  1297. ttime = (float)((double)n * dz->frametime);
  1298. if(dz->brksize[PS_TFRAME]) {
  1299. if((exit_status = read_value_from_brktable(ttime,PS_TFRAME,dz))<0)
  1300. return(exit_status);
  1301. interpfact = round(dz->param[PS_TFRAME]/dz->frametime);
  1302. }
  1303. } while(dz->pitches[n]<MINPITCH);
  1304. }
  1305. n = lastn;
  1306. if((exit_status = hztomidi(&lastmidi,dz->pitches[n]))<0)
  1307. return(exit_status);
  1308. }
  1309. if(n < dz->wlength-1)
  1310. if((exit_status = do_tail(n,lastmidi,dz))<0)
  1311. return(exit_status);
  1312. return(FINISHED);
  1313. }
  1314. /***************************** SPECPTRANSPOSE *****************/
  1315. int specptranspose(dataptr dz)
  1316. {
  1317. int n;
  1318. for(n=0;n<dz->wlength;n++) {
  1319. if(dz->pitches[n]<MINPITCH)
  1320. continue;
  1321. dz->pitches[n] = (float)(dz->pitches[n] * dz->param[PT_TVAL]);
  1322. check_pitch(&(dz->pitches[n]),dz);
  1323. }
  1324. return(FINISHED);
  1325. }
  1326. /***************************** SPECPVIB *****************/
  1327. int specpvib(dataptr dz)
  1328. {
  1329. int exit_status;
  1330. double indexf = 0.0, intvl, indexstep;
  1331. int index = 0;
  1332. int n;
  1333. dz->time = 0.0f;
  1334. if((exit_status = read_values_from_all_existing_brktables((double)dz->time,dz))<0)
  1335. return(exit_status);
  1336. indexstep = dz->param[PV_FRQ] * dz->frametime * (double)P_TABSIZE;
  1337. for(n=0;n<dz->wlength;n++) {
  1338. if(dz->pitches[n]<MINPITCH)
  1339. continue;
  1340. intvl = dz->parray[PV_SIN][index] * dz->param[PV_RANG];
  1341. intvl = pow(SEMITONE_INTERVAL,intvl);
  1342. if(dz->is_transpos) {
  1343. dz->transpos[n] = (float)intvl;
  1344. check_transpos(&(dz->transpos[n]),dz);
  1345. } else {
  1346. dz->pitches[n] = (float)(dz->pitches[n] * intvl);
  1347. check_pitch(&(dz->pitches[n]),dz);
  1348. }
  1349. indexf += indexstep;
  1350. index = round(indexf) % P_TABSIZE;
  1351. dz->time = (float)(dz->time + dz->frametime);
  1352. if(dz->brksize[PV_FRQ]) {
  1353. if((exit_status = read_value_from_brktable((double)dz->time,PV_FRQ,dz))<0)
  1354. return(exit_status);
  1355. indexstep = dz->param[PV_FRQ] * dz->frametime * (double)P_TABSIZE;
  1356. }
  1357. if(dz->brksize[PV_RANG]) {
  1358. if((exit_status = read_value_from_brktable((double)dz->time,PV_RANG,dz))<0)
  1359. return(exit_status);
  1360. }
  1361. }
  1362. return(FINISHED);
  1363. }
  1364. /*************************** SPECREPITCH ********************/
  1365. int specrepitch(dataptr dz)
  1366. {
  1367. int exit_status;
  1368. int n, brklen;
  1369. float frametime;
  1370. if(dz->wlength == 0) { /* brkpnt only data entered */
  1371. dz->wlength = round(dz->duration/DEFAULT_FRAMETIME);
  1372. frametime = DEFAULT_FRAMETIME;
  1373. } else
  1374. frametime = dz->frametime;
  1375. switch(dz->mode) {
  1376. case(PPT): case(PPT_TO_BRK): /* PPT */
  1377. if((dz->transpos = (float *)malloc(dz->wlength * sizeof(float)))==NULL) {
  1378. sprintf(errstr,"INSUFFICIENT MEMORY for transpositions array.\n");
  1379. return(MEMORY_ERROR);
  1380. }
  1381. for(n=0;n<dz->wlength;n++) {
  1382. if(dz->pitches[n]<MINPITCH || dz->pitches2[n]<MINPITCH)
  1383. dz->transpos[n] = 1.0f;
  1384. else
  1385. dz->transpos[n] = (float)(dz->pitches2[n]/dz->pitches[n]);
  1386. check_transpos(&(dz->transpos[n]),dz);
  1387. }
  1388. break;
  1389. case(PTP): case(PTP_TO_BRK): /* PTP */
  1390. for(n=0;n<dz->wlength;n++) {
  1391. if(dz->pitches[n] < MINPITCH)
  1392. continue;
  1393. dz->pitches[n] = (float)(dz->pitches[n] * dz->transpos[n]);
  1394. check_pitch(&(dz->pitches[n]),dz);
  1395. }
  1396. break;
  1397. case(TTT): case(TTT_TO_BRK): /* TTT */
  1398. for(n=0;n<dz->wlength;n++) {
  1399. dz->transpos[n] = (float)(dz->transpos[n] * dz->transpos2[n]);
  1400. check_transpos(&(dz->transpos[n]),dz);
  1401. }
  1402. break;
  1403. default:
  1404. sprintf(errstr,"unknown case in specrepitch()\n");
  1405. return(PROGRAM_ERROR);
  1406. }
  1407. switch(dz->mode) {
  1408. case(PTP): /* out P-bin */
  1409. if((exit_status = write_samps(dz->pitches,dz->wlength,dz))<0)
  1410. return(exit_status);
  1411. break;
  1412. case(PPT):
  1413. case(TTT): /* out T-bin */
  1414. dz->outfiletype = TRANSPOS_OUT;
  1415. if((exit_status = write_samps(dz->transpos,dz->wlength,dz))<0)
  1416. return(exit_status);
  1417. dz->is_transpos = TRUE;
  1418. break;
  1419. case(PTP_TO_BRK): /* P-brk out */
  1420. if((dz->parray[RP_TBRK]
  1421. = (double *)malloc(dz->wlength * sizeof(double) * 2))==NULL) {
  1422. sprintf(errstr,"INSUFFICIENT MEMORY for pitch brkpnt array.\n");
  1423. return(MEMORY_ERROR);
  1424. }
  1425. if((exit_status = interpolate_pitch(dz->pitches,0,dz))<0)
  1426. return(exit_status);
  1427. if((exit_status = convert_pch_or_transpos_data_to_brkpnttable(
  1428. &brklen,dz->pitches,frametime,RP_TBRK,dz))<0)
  1429. return(exit_status);
  1430. if((exit_status = write_brkfile(dz->fp,brklen,RP_TBRK,dz))<0)
  1431. return(exit_status);
  1432. break;
  1433. case(PPT_TO_BRK):
  1434. case(TTT_TO_BRK): /* T_brk out */
  1435. if((dz->parray[RP_TBRK]
  1436. = (double *)malloc(dz->wlength * sizeof(double) * 2))==NULL) {
  1437. sprintf(errstr,"INSUFFICIENT MEMORY for transposition brkpnt array.\n");
  1438. return(MEMORY_ERROR);
  1439. }
  1440. if((exit_status = convert_pch_or_transpos_data_to_brkpnttable(&brklen,dz->transpos,frametime,RP_TBRK,dz))<0)
  1441. return(exit_status);
  1442. if((exit_status = write_brkfile(dz->fp,brklen,RP_TBRK,dz))<0)
  1443. return(exit_status);
  1444. break;
  1445. }
  1446. return(FINISHED);
  1447. }
  1448. /******************************* DO_PITCH_CUT ******************************/
  1449. int do_pitch_cut(dataptr dz)
  1450. { int n;
  1451. for(n=dz->iparam[PF_SCUTW];n<dz->iparam[PF_ECUTW];n++)
  1452. dz->pitches[n] = (float)NOT_PITCH;
  1453. return(FINISHED);
  1454. }
  1455. /************************* DO_PITCH_SMOOTHING ***************************/
  1456. int do_pitch_smoothing(dataptr dz)
  1457. {
  1458. int exit_status;
  1459. int z;
  1460. int first_valid_pitch, n, wlength_less_2 = dz->wlength - 2;
  1461. double *slopechange;
  1462. if((slopechange = (double *)malloc(dz->wlength * sizeof(double)))==NULL) {
  1463. sprintf(errstr,"INSUFFICIENT MEMORY for slopechange array.\n");
  1464. return(MEMORY_ERROR);
  1465. }
  1466. for(z=0;z<dz->iparam[PF_SMOOTH];z++) {
  1467. if((exit_status = skip_to_first_pitch(&first_valid_pitch,dz))<0)
  1468. return(exit_status);
  1469. if((exit_status = calc_slopechanges(first_valid_pitch,slopechange,dz))<0)
  1470. return(exit_status);
  1471. for(n=1;n<wlength_less_2;n++) {
  1472. if(fabs(slopechange[n]) > GLARG) {
  1473. if(dz->pitches[n+1]<0.0)
  1474. continue;
  1475. if((exit_status = is_start_of_glitch(n,slopechange,dz))<0)
  1476. return(exit_status);
  1477. if(exit_status==TRUE)
  1478. continue; /* WILL BE SMOOTHED OUT AT NEXTSTEP */
  1479. if(dz->pitches[n-1]<MINPITCH) { /* ONSET SMOOTH */
  1480. if((exit_status = do_onset_smooth(n,slopechange,dz))<0)
  1481. return(exit_status);
  1482. continue;
  1483. }
  1484. if(n>=2 && dz->pitches[n-2]<MINPITCH) { /* DOUBLE ONSET SMOOTH */
  1485. if((exit_status = do_double_onset_smooth(n,slopechange,dz))<0)
  1486. return(exit_status);
  1487. continue;
  1488. } /* NORMAL SMOOTH */
  1489. if((exit_status = do_smooth(n,slopechange,dz))<0)
  1490. return(exit_status);
  1491. }
  1492. }
  1493. }
  1494. free(slopechange);
  1495. return(FINISHED);
  1496. }
  1497. /****************************** DO_SMOOTH **************************
  1498. *
  1499. * Including checking for end of a pitched segment.
  1500. */
  1501. int do_smooth(int pitchno,double *slopechange,dataptr dz)
  1502. {
  1503. double val, val0, val1;
  1504. if(slopechange[pitchno+1] > GLARG && pitchno>=1) {
  1505. if(pitchno+2 < dz->wlength && dz->pitches[pitchno+2] < 0.0) {
  1506. val0 = log10(dz->pitches[pitchno-1]); /* TAIL */
  1507. val1 = log10(dz->pitches[pitchno]);
  1508. val = val1 - val0;
  1509. dz->pitches[pitchno+1] = (float)pow((double)10,(val1 + val));
  1510. slopechange[pitchno] = 0.0; /* CORRECT SLOPECHANGE APPROPRIATELY */
  1511. slopechange[pitchno+1] = 0.0; /* AVOID SPURIOUS SMOOTH AT END_OF_TAIL PITCH */
  1512. return(FINISHED);
  1513. } else {
  1514. if(pitchno+3 < dz->wlength && dz->pitches[pitchno+3] < MINPITCH) {
  1515. val0 = log10(dz->pitches[pitchno-1]); /* DOUBLE TAIL */
  1516. val1 = log10(dz->pitches[pitchno]);
  1517. val = val1 - val0;
  1518. dz->pitches[pitchno+1] = (float)pow((double)10,(val1 + val));
  1519. val += val;
  1520. dz->pitches[pitchno+2] = (float)pow((double)10,(val1 + val));
  1521. slopechange[pitchno] = 0.0; /* CORRECT SLOPECHANGES APPROPRIATELY */
  1522. slopechange[pitchno+1] = 0.0;
  1523. slopechange[pitchno+2] = 0.0; /* AVOID SPURIOUS SMOOTH AT END_OF_TAIL PITCH */
  1524. return(FINISHED);
  1525. }
  1526. }
  1527. } /* NORMAL */
  1528. val0 = log10(dz->pitches[pitchno-1]);
  1529. val1 = log10(dz->pitches[pitchno+1]);
  1530. val = (val0 + val1)/2.0;
  1531. dz->pitches[pitchno] = (float)pow((double)10,val);
  1532. slopechange[pitchno] = 0.0; /* CORRECT SLOPECHANGE APPROPRIATELY */
  1533. return(FINISHED);
  1534. }
  1535. /************************ SKIP_TO_FIRST_PITCH ***********************/
  1536. int skip_to_first_pitch(int *first_pitch,dataptr dz)
  1537. {
  1538. *first_pitch = 0;
  1539. while(dz->pitches[*first_pitch] < MINPITCH) {
  1540. if(++(*first_pitch) >= dz->wlength) {
  1541. sprintf(errstr,"No pitch data found.\n");
  1542. return(DATA_ERROR);
  1543. }
  1544. }
  1545. if(++(*first_pitch) >= dz->wlength) {
  1546. sprintf(errstr,"No pitch data found.\n");
  1547. return(DATA_ERROR);
  1548. }
  1549. return(FINISHED);
  1550. }
  1551. /************************* CALC_SLOPECHANGES ***********************/
  1552. int calc_slopechanges(int first_valid_pitch,double *slopechange,dataptr dz)
  1553. {
  1554. int n, k, wlength_less_1 = dz->wlength - 1;
  1555. int OK = 1;
  1556. double preslope = 0.0, postslope;
  1557. for(n=0;n<dz->wlength;n++)
  1558. slopechange[n] = 0.0;
  1559. for(n = first_valid_pitch;n<wlength_less_1;n++) {
  1560. k = 1;
  1561. while(dz->pitches[n+k] < 0.0) {
  1562. k++;
  1563. if(k+n >= dz->wlength) {
  1564. OK = 0;
  1565. break;
  1566. }
  1567. if(!OK)
  1568. break;
  1569. }
  1570. if(!OK)
  1571. break;
  1572. postslope = (log10(dz->pitches[n+k]) - log10(dz->pitches[n]))/(double)k;
  1573. slopechange[n] = postslope - preslope;
  1574. n += k - 1;
  1575. preslope = postslope;
  1576. }
  1577. return(FINISHED);
  1578. }
  1579. /********************** IS_START_OF_GLITCH **********************
  1580. *
  1581. * WITHOUT THOROUGH CHECK worried that logs may get 0 or -ve vals..
  1582. */
  1583. int is_start_of_glitch(int pitchno,double *slopechange,dataptr dz)
  1584. {
  1585. double val, val0, val1;
  1586. if(dz->vflag[PF_TWOW]) {
  1587. if(pitchno+3 < dz->wlength-1
  1588. && fabs(slopechange[pitchno+1]) > GLARG
  1589. && fabs(slopechange[pitchno+2]) > GLARG
  1590. && fabs(slopechange[pitchno+3]) > GLARG
  1591. && ((slopechange[pitchno] > 0.0
  1592. && slopechange[pitchno+1] < 0.0
  1593. && slopechange[pitchno+2] < 0.0
  1594. && slopechange[pitchno+3] > 0.0) /* +--+ */
  1595. || (slopechange[pitchno] < 0.0
  1596. && slopechange[pitchno+1] > 0.0
  1597. && slopechange[pitchno+2] < 0.0
  1598. && slopechange[pitchno+3] > 0.0) /* -++- */
  1599. )
  1600. ){
  1601. val0 = log10(dz->pitches[pitchno]);
  1602. val1 = log10(dz->pitches[pitchno+3]);
  1603. val = (val1 - val0)/3.0; /* 2 WINDOW GLITCH */
  1604. val0 = log10(dz->pitches[pitchno] + val);
  1605. dz->pitches[pitchno+1] = (float)pow((double)10,val0);
  1606. val += val;
  1607. val1 = log10(dz->pitches[pitchno] + val);
  1608. dz->pitches[pitchno+2] = (float)pow((double)10,val1);
  1609. slopechange[pitchno+1] = 0.0;
  1610. slopechange[pitchno+2] = 0.0;
  1611. return(TRUE);
  1612. }
  1613. }
  1614. if(fabs(slopechange[pitchno+1]) > GLARG
  1615. && fabs(slopechange[pitchno+2]) > GLARG
  1616. && ((slopechange[pitchno] > 0.0
  1617. && slopechange[pitchno+1] < 0.0
  1618. && slopechange[pitchno+2] > 0.0) /* +-+ */
  1619. || (slopechange[pitchno] < 0.0
  1620. && slopechange[pitchno+1] > 0.0
  1621. && slopechange[pitchno+2] < 0.0) /* -+- */
  1622. )
  1623. )
  1624. return(TRUE);
  1625. return(FALSE);
  1626. }
  1627. /*********************** DO_ONSET_SMOOTH ********************/
  1628. int do_onset_smooth(int pitchno, double *slopechange,dataptr dz)
  1629. {
  1630. double val, val0, val1;
  1631. if(dz->pitches[pitchno+2] < MINPITCH)
  1632. return(FINISHED);
  1633. val0 = log10(dz->pitches[pitchno+1]);
  1634. val1 = log10(dz->pitches[pitchno+2]);
  1635. val = (2.0 * val0) - val1;
  1636. dz->pitches[pitchno] = (float)pow((double)10,val);
  1637. slopechange[pitchno+1] = 0.0; /* CHANGE OF SLOPE HENCE BECOMES ZERO AT NEXT PITCH */
  1638. return(FINISHED);
  1639. } /* THIS ALSO PREVENTS double_onset BEING CALLED SPURIOUSLY */
  1640. /************************ DO_DOUBLE_ONSET_SMOOTH ********************
  1641. *
  1642. * NORMAL DOUBLE ONSET GLITCH SITUATION TO BE AVOIDED
  1643. * .
  1644. * .
  1645. * .
  1646. * postslope .
  1647. * ...... X---X---X X
  1648. * / / \postslope
  1649. * / / \
  1650. * X---X X---X X---X
  1651. * | |
  1652. * | |
  1653. * 0...| 0...|
  1654. *
  1655. * X
  1656. * |\
  1657. * reverse predict from postslope, OK | \reverse predict from postslope
  1658. * X---X---X---X---X | \ gives spurious glitch
  1659. * | | X
  1660. * | | \
  1661. * | | \
  1662. * | | \
  1663. * | | X
  1664. * 0...| | \
  1665. * | \
  1666. * | X---X
  1667. * |
  1668. * |
  1669. * 0...|
  1670. * ,X
  1671. * / \
  1672. * interp instead ,X \
  1673. * / \
  1674. * X X---X
  1675. * |
  1676. * |
  1677. * 0...|
  1678. *
  1679. * and at next pass, there'll probably be a 2nd interp thus..
  1680. *
  1681. * ,X.
  1682. * / 'X.
  1683. * X ' X---X
  1684. * |
  1685. * |
  1686. * 0...|
  1687. *
  1688. *
  1689. */
  1690. int do_double_onset_smooth(int pitchno,double *slopechange,dataptr dz)
  1691. {
  1692. double val, val0, val1, preslope, postslope, pn0 ,pn1, pn2;
  1693. if(dz->pitches[pitchno+2] < MINPITCH)
  1694. return(FINISHED);
  1695. pn0 = log10(dz->pitches[pitchno]);
  1696. pn1 = log10(dz->pitches[pitchno+1]);
  1697. pn2 = log10(dz->pitches[pitchno+2]);
  1698. preslope = fabs(pn1 - pn0);
  1699. postslope = fabs(pn2 - pn1);
  1700. if(postslope > preslope * SLOPE_FUDGE) { /* 1 */
  1701. val0 = log10(dz->pitches[pitchno-1]); /* IF SLOPE AHEAD LOOKS TOO BIG */
  1702. val1 = pn1; /* DON'T RISK USING IT TO GET VALS HERE. */
  1703. val = (val0 + val1)/2.0; /* INTERP INSTEAD */
  1704. dz->pitches[pitchno] = (float)pow((double)10,val);
  1705. slopechange[pitchno] = 0.0; /* CORRECT SLOPECHANGE APPROPRIATELY */
  1706. } else {
  1707. val0 = pn1; /* OTHERWISE BASE VALS ON SLOPE AHEAD */
  1708. val1 = pn2;
  1709. val = (2.0 * val0) - val1;
  1710. dz->pitches[pitchno] = (float)pow((double)10,val);
  1711. val = (3.0 * val0) - (2.0 * val1);
  1712. dz->pitches[pitchno-1] = (float)pow((double)10,val);
  1713. slopechange[pitchno] = 0.0;
  1714. slopechange[pitchno+1] = 0.0; /* CORRECT SLOPECHANGES APPROPRIATELY */
  1715. }
  1716. return(FINISHED);
  1717. }
  1718. /********************** GET_MAX_AND_MIN_PITCHES **********************/
  1719. int get_max_and_min_pitches(double *maxpitch,double *minpitch,dataptr dz)
  1720. {
  1721. int n;
  1722. for(n=0;n<dz->wlength;n++) {
  1723. if(dz->pitches[n] > MINPITCH) {
  1724. if(dz->pitches[n] > *maxpitch)
  1725. *maxpitch = dz->pitches[n];
  1726. if(dz->pitches[n] < *minpitch)
  1727. *minpitch = dz->pitches[n];
  1728. }
  1729. }
  1730. return(FINISHED);
  1731. }
  1732. /***************************** WRITE_REMAINING_PITCH_OR_TRANSPOS_DATA ******************************/
  1733. int write_remaining_pitch_or_transpos_data(int final_length_in_windows,dataptr dz)
  1734. {
  1735. int exit_status;
  1736. if(final_length_in_windows > 0) {
  1737. if(dz->is_transpos) {
  1738. if((exit_status = write_samps(dz->transpos,final_length_in_windows,dz))<0)
  1739. return(exit_status);
  1740. }else {
  1741. if((exit_status = write_samps(dz->pitches,final_length_in_windows,dz))<0)
  1742. return(exit_status);
  1743. }
  1744. }
  1745. return(FINISHED);
  1746. }
  1747. /***************************** GET_MIDIMEAN ******************************/
  1748. int get_midimean(double *midimean,dataptr dz)
  1749. {
  1750. int exit_status;
  1751. int n;
  1752. double val;
  1753. *midimean = 0.0;
  1754. for(n=0;n<dz->wlength;n++) {
  1755. if(dz->pitches[n]<MINPITCH)
  1756. continue;
  1757. if((exit_status = hztomidi(&val,dz->pitches[n]))<0)
  1758. return(exit_status);
  1759. *midimean += val;
  1760. }
  1761. *midimean /= (double)dz->wlength;
  1762. return(FINISHED);
  1763. }
  1764. /***************************** SET_PVAL ******************************/
  1765. int set_pval(double midivalue,int n,dataptr dz)
  1766. {
  1767. if(dz->is_transpos) {
  1768. dz->transpos[n] = (float)(miditohz(midivalue)/dz->pitches[n]);
  1769. check_transpos(&(dz->transpos[n]),dz);
  1770. } else {
  1771. dz->pitches[n] = (float)miditohz(midivalue);
  1772. check_pitch(&(dz->pitches[n]),dz);
  1773. }
  1774. return(FINISHED);
  1775. }
  1776. /***************************************** DO_TAIL ************************/
  1777. int do_tail(int n,double lastmidi,dataptr dz)
  1778. {
  1779. int exit_status;
  1780. double thispich, thismidi, endmidi, mdiff, step;
  1781. int diff, m, z;
  1782. if(dz->vflag[PS_HOLD]) {
  1783. thispich = dz->pitches[n];
  1784. n++;
  1785. while(n < dz->wlength) {
  1786. if(dz->pitches[n]<MINPITCH) {
  1787. n++;
  1788. continue;
  1789. }
  1790. if(dz->is_transpos) {
  1791. dz->transpos[n] = (float)(thispich/dz->pitches[n]);
  1792. check_transpos(&(dz->transpos[n]),dz);
  1793. } else {
  1794. dz->pitches[n] = (float)thispich;
  1795. check_pitch(&(dz->pitches[n]),dz);
  1796. }
  1797. n++;
  1798. }
  1799. } else {
  1800. z = dz->wlength-1;
  1801. while(dz->pitches[z]<MINPITCH) {
  1802. if(--z==n)
  1803. return(FINISHED);
  1804. }
  1805. if((exit_status = hztomidi(&endmidi,dz->pitches[z]))<0)
  1806. return(exit_status);
  1807. mdiff = endmidi - lastmidi;
  1808. if((diff = z - n)<2)
  1809. return(FINISHED);
  1810. step = mdiff/(double)diff;
  1811. n++;
  1812. for(m=1;n <= z;n++,m++) {
  1813. if(dz->pitches[n]<MINPITCH)
  1814. continue;
  1815. thismidi = lastmidi + (step * (double)m);
  1816. if((exit_status = set_pval(thismidi,n,dz))<0)
  1817. return(exit_status);
  1818. }
  1819. }
  1820. return(FINISHED);
  1821. }
  1822. /************************** GET_PITCHAPPROX_AVERAGES ************************/
  1823. int get_pitchapprox_averages(int *avcnt,dataptr dz)
  1824. {
  1825. int exit_status;
  1826. int OK = 1, n = 0, m, cnt;
  1827. double val;
  1828. *avcnt = 0;
  1829. if((dz->parray[PA_AVPICH] = (double *)malloc(dz->wlength * sizeof(double)))==NULL) {
  1830. sprintf(errstr,"INSUFFICIENT MEMORY for averaging array.\n");
  1831. return(MEMORY_ERROR);
  1832. }
  1833. while(OK) {
  1834. dz->parray[PA_AVPICH][*avcnt] = 0.0;
  1835. m = 0;
  1836. cnt = 0;
  1837. while(m < BLOKCNT) {
  1838. if(dz->pitches[n]<MINPITCH) {
  1839. m++;
  1840. if(++n >= dz->wlength) {
  1841. OK = 0;
  1842. break;
  1843. }
  1844. continue;
  1845. }
  1846. if((exit_status = hztomidi(&val,dz->pitches[n]))<0)
  1847. return(exit_status);
  1848. dz->parray[PA_AVPICH][*avcnt] += val;
  1849. cnt++;
  1850. m++;
  1851. if(++n >= dz->wlength) {
  1852. OK = 0;
  1853. break;
  1854. }
  1855. }
  1856. if(cnt==0)
  1857. dz->parray[PA_AVPICH][*avcnt] = -1.0f;
  1858. else {
  1859. dz->parray[PA_AVPICH][*avcnt] /= (double)cnt;
  1860. dz->parray[PA_AVPICH][*avcnt] = miditohz(dz->parray[PA_AVPICH][*avcnt]);
  1861. }
  1862. (*avcnt)++;
  1863. }
  1864. return(FINISHED);
  1865. }
  1866. /********************************** APPROX_FUNC1 **********************************/
  1867. int approx_func1(int *newlength_of_data,int *is_firsttime,
  1868. double *lastmidi,int *lastpos,int n,dataptr dz)
  1869. {
  1870. int q, m, thispos, diff;
  1871. int exit_status = CONTINUE;
  1872. double ttime, thismidi, wiggle, this_prange, this_trange, mididiff, midistep;
  1873. int here = min(dz->wlength-1,n * BLOKCNT); /* just being ultra careful !! */
  1874. for(q=here;q<here+BLOKCNT;q++) {
  1875. if(q>=dz->wlength)
  1876. break;
  1877. if(dz->pitches[q] > MINPITCH)
  1878. break;
  1879. }
  1880. if(q>=here+BLOKCNT || q>=dz->wlength) /* No valid pitchdata here !! */
  1881. return(CONTINUE);
  1882. here = q;
  1883. ttime = dz->frametime * (double)here;
  1884. if((exit_status = hztomidi(&thismidi,dz->pitches[here]))<0)
  1885. return(exit_status);
  1886. if(dz->brksize[PA_PRANG]) { /* RWD need curly */
  1887. if((exit_status = read_value_from_brktable(ttime,PA_PRANG,dz))<0)
  1888. return(exit_status);
  1889. }
  1890. wiggle = (drand48() * 2.0) -1.0; /* random +- */
  1891. this_prange = wiggle * dz->param[PA_PRANG];
  1892. thismidi += this_prange;
  1893. if(*is_firsttime) {
  1894. if((exit_status = set_pval(thismidi,q,dz))<0)
  1895. return(exit_status);
  1896. *lastpos = q;
  1897. *lastmidi = thismidi;
  1898. *is_firsttime = FALSE;
  1899. } else {
  1900. wiggle = (drand48() * 2.0) -1.0;
  1901. if(dz->brksize[PA_TRANG]) { /* RWD need curly */
  1902. if((exit_status = read_value_from_brktable(ttime,PA_TRANG,dz))<0)
  1903. return(exit_status);
  1904. }
  1905. this_trange = dz->param[PA_TRANG] * wiggle;
  1906. ttime += this_trange;
  1907. thispos = round(ttime/dz->frametime);
  1908. thispos = max(0L,thispos);
  1909. if((diff = thispos - *lastpos)>0) {
  1910. if(thispos > (*newlength_of_data)-1) {
  1911. if(dz->is_transpos) {
  1912. thispos = (*newlength_of_data)-1;
  1913. exit_status = FINISHED;
  1914. } else {
  1915. *newlength_of_data = thispos + 1;
  1916. if((dz->pitches = (float *)realloc((char *)dz->pitches,
  1917. (*newlength_of_data) * sizeof(float)))==NULL) {
  1918. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate pitch array.\n");
  1919. return(MEMORY_ERROR);
  1920. }
  1921. }
  1922. }
  1923. mididiff = thismidi - *lastmidi;
  1924. midistep = mididiff/(double)diff;
  1925. for(m=1,q= *lastpos + 1;m<=diff;m++,q++) {
  1926. if(q < dz->wlength && dz->pitches[q]<MINPITCH)
  1927. continue;
  1928. thismidi = *lastmidi + (midistep * (double)m);
  1929. if((exit_status = set_pval(thismidi,q,dz))<0)
  1930. return(exit_status);
  1931. }
  1932. *lastmidi = thismidi;
  1933. *lastpos = thispos;
  1934. }
  1935. }
  1936. return(exit_status);
  1937. }
  1938. /********************************** APPROX_FUNC2 **********************************/
  1939. int approx_func2(int *newlength_of_data,double lastmidi,int lastpos,int avcnt,dataptr dz)
  1940. {
  1941. int exit_status;
  1942. int q, n, thispos, diff = 0;
  1943. double thismidi,ttime, wiggle, this_prange, this_trange;
  1944. double mididiff, midistep;
  1945. q = avcnt-1;
  1946. while(dz->parray[PA_AVPICH][q]<0.0) {
  1947. if(--q<=lastpos)
  1948. return(FINISHED);
  1949. }
  1950. if((exit_status = hztomidi(&thismidi,dz->parray[PA_AVPICH][q]))<0)
  1951. return(exit_status);
  1952. ttime = (q * BLOKCNT) * dz->frametime;
  1953. if(dz->brksize[PA_PRANG]) { //RWD need curly
  1954. if((exit_status = read_value_from_brktable(ttime,PA_PRANG,dz))<0)
  1955. return(exit_status);
  1956. }
  1957. wiggle = (drand48() * 2.0) -1.0; /* random +- */
  1958. this_prange = wiggle * dz->param[PA_PRANG];
  1959. thismidi += this_prange;
  1960. if(dz->is_transpos)
  1961. thispos = dz->wlength-1;
  1962. else {
  1963. wiggle = (drand48() * 2.0) -1.0; /* random +- */
  1964. if(dz->brksize[PA_TRANG]) { /* RWD need curly */
  1965. if((exit_status = read_value_from_brktable(ttime,PA_TRANG,dz))<0)
  1966. return(exit_status);
  1967. }
  1968. this_trange = dz->param[PA_TRANG] * wiggle;
  1969. ttime += this_trange;
  1970. thispos = round(ttime/dz->frametime);
  1971. thispos = max(0L,thispos);
  1972. if((diff = thispos - lastpos)>0 && thispos > *newlength_of_data-1) {
  1973. *newlength_of_data = thispos + 1;
  1974. if((dz->pitches =
  1975. (float *)realloc((char *)dz->pitches,*newlength_of_data * sizeof(float)))==NULL) {
  1976. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate pitch array.\n");
  1977. return(MEMORY_ERROR);
  1978. }
  1979. }
  1980. }
  1981. if(diff>0) {
  1982. mididiff = thismidi - lastmidi;
  1983. midistep = mididiff/(double)diff;
  1984. for(n=1,q=lastpos+1;n<=diff;n++,q++) {
  1985. if(q < dz->wlength && dz->pitches[q]<MINPITCH)
  1986. continue;
  1987. thismidi = lastmidi + (midistep * (double)n);
  1988. if((exit_status = set_pval(thismidi,q,dz))<0)
  1989. return(exit_status);
  1990. }
  1991. } else
  1992. *newlength_of_data = lastpos + 1;
  1993. return(FINISHED);
  1994. }
  1995. /************************** GET_RAND_INTERVAL ************************/
  1996. int get_rand_interval(double *thisintv,dataptr dz)
  1997. {
  1998. double wiggle = ((drand48() * 2.0) - 1.0);
  1999. if(dz->vflag[PR_IS_SLEW]) {
  2000. if(wiggle < dz->param[PR_SLEW]
  2001. || (dz->iparam[PR_NEGATIV_SLEW]==TRUE
  2002. && (wiggle > dz->param[PR_SLEW])))
  2003. wiggle = -wiggle;
  2004. }
  2005. *thisintv = dz->param[PR_MXINT] * wiggle;
  2006. return(FINISHED);
  2007. }
  2008. /************************** INTERVAL_MAPPING ************************
  2009. *
  2010. * Approximate input interval to nearest value in LHS column of input map.
  2011. * Find variance from that value.
  2012. * Return corresponding value in RHS column of map, with the variance correction added.
  2013. */
  2014. int interval_mapping(double *thisint,double thismidi,dataptr dz)
  2015. {
  2016. double *p = dz->parray[PI_INTMAP];
  2017. double *pend = dz->parray[PI_INTMAP] + (dz->itemcnt * 2);
  2018. double variance, v1, v2;
  2019. if(thismidi <= *p) { /* intvl is below all entries in mapping table */
  2020. variance = thismidi - *p;
  2021. *thisint = *(p+1) - variance; /* return map of bottom val (-variance) */
  2022. return(FINISHED);
  2023. }
  2024. while(thismidi > *p) {
  2025. p += 2;
  2026. if(p >= pend) { /* intvl is above all entries in mapping table */
  2027. p -= 2;
  2028. variance = thismidi - *p;
  2029. *thisint = *(p+1) - variance;/* return map of top val (-variance) */
  2030. return(FINISHED);
  2031. }
  2032. }
  2033. v1 = *p - thismidi; /* intvl is between 2 entries in mapping table */
  2034. v2 = thismidi - *(p-2);
  2035. if(v1 > v2) { /* Compare variances, to find which intvl closer */
  2036. variance = v2;
  2037. *thisint = *(p-1) - variance;
  2038. } else {
  2039. variance = v1;
  2040. *thisint = *(p+1) + variance; /* return appropriate mapped pitch (+/-variance) */
  2041. }
  2042. return(FINISHED);
  2043. }
  2044. /************************************** PEAK_INTERP ****************/
  2045. int peak_interp
  2046. (int pitchno,int last_validpitch_no,int *lastmaxpos,double meanpich,
  2047. double minint,double maxint,double *lastmidi,dataptr dz)
  2048. {
  2049. int exit_status;
  2050. double thispitch, thismidi, variance, mdiff,step;
  2051. int m, k, maxpos = 0, minpos = 0, diff;
  2052. double maxvar = 0.0, minvar = 0.0;
  2053. k = pitchno - last_validpitch_no;
  2054. for(m=0;m<k;m++) {
  2055. if((thispitch = dz->pitches[k+m])<MINPITCH)
  2056. continue;
  2057. if(thispitch >= meanpich) {
  2058. if((variance = thispitch/meanpich)>maxvar) {
  2059. maxvar = variance;
  2060. maxpos = k+m;
  2061. }
  2062. } else {
  2063. if((variance = meanpich/thispitch)>minvar) {
  2064. minvar = variance;
  2065. minpos = k+m;
  2066. }
  2067. }
  2068. //TW avoid log(0)
  2069. if(minvar > 0.0)
  2070. minvar = LOG2(minvar) * 12.0;
  2071. //TW avoid log(0)
  2072. if(maxvar > 0.0)
  2073. maxvar = LOG2(maxvar) * 12.0;
  2074. minvar /= minint;
  2075. maxvar /= maxint; /* NORMALISE */
  2076. if(maxvar < minvar)
  2077. maxpos = minpos;
  2078. }
  2079. diff = maxpos - *lastmaxpos;
  2080. if((exit_status = hztomidi(&thismidi,dz->pitches[maxpos]))<0)
  2081. return(exit_status);
  2082. mdiff = thismidi - *lastmidi;
  2083. step = mdiff/(double)diff;
  2084. for(m=1;m<=diff;m++) {
  2085. thismidi = *lastmidi + (step * (double)m);
  2086. if(dz->pitches[(*lastmaxpos)+m]<MINPITCH)
  2087. continue;
  2088. if((exit_status = set_pval(thismidi,(*lastmaxpos)+m,dz))<0)
  2089. return(exit_status);
  2090. }
  2091. *lastmidi = thismidi;
  2092. *lastmaxpos = maxpos;
  2093. return(FINISHED);
  2094. }
  2095. /*************************** DO_PITCH_FILTER *************************/
  2096. int do_pitch_filter(dataptr dz)
  2097. {
  2098. int n;
  2099. switch(dz->iparam[PF_ISFILTER]) {
  2100. case(IS_HIPASS):
  2101. for(n=0;n<dz->wlength;n++) {
  2102. if(dz->pitches[n] < dz->param[PF_LOF])
  2103. dz->pitches[n] = (float)NOT_PITCH;
  2104. }
  2105. break;
  2106. case(IS_LOPASS):
  2107. for(n=0;n<dz->wlength;n++) {
  2108. if(dz->pitches[n] > dz->param[PF_HIF])
  2109. dz->pitches[n] = (float)NOT_PITCH;
  2110. }
  2111. break;
  2112. case(IS_BANDPASS):
  2113. for(n=0;n<dz->wlength;n++) {
  2114. if(dz->pitches[n] < dz->param[PF_LOF] || dz->pitches[n] > dz->param[PF_HIF])
  2115. dz->pitches[n] = (float)NOT_PITCH;
  2116. }
  2117. break;
  2118. }
  2119. return(FINISHED);
  2120. }
  2121. /***************************** TIDY_UP_PITCH_DATA ***********************/
  2122. int tidy_up_pitch_data(dataptr dz)
  2123. {
  2124. int exit_status;
  2125. if((exit_status = anti_noise_smoothing(dz->wlength,dz->pitches,dz->frametime))<0)
  2126. return(exit_status);
  2127. if((exit_status = mark_zeros_in_pitchdata(dz))<0)
  2128. return(exit_status);
  2129. if((exit_status = eliminate_blips_in_pitch_data(dz))<0)
  2130. return(exit_status);
  2131. if(dz->vflag[KEEP_PITCH_ZEROS]==FALSE)
  2132. return interpolate_pitch(dz->pitches,1,dz);
  2133. return pitch_found(dz);
  2134. }
  2135. /************************* GENERATE_TONE *************************/
  2136. int generate_tone(dataptr dz)
  2137. {
  2138. #define VOLUME_PAD (0.3)
  2139. #define NOISEBASE (0.2)
  2140. int exit_status;
  2141. int m, done, cc, vc, partials_in_test_tone;
  2142. float thisamp;
  2143. double thisfrq, basefrq;
  2144. int n = 0, last_partial;
  2145. double noisrange = 1.0 - NOISEBASE;
  2146. double level, totamp = 0.0;
  2147. dz->flbufptr[0] = dz->bigfbuf;
  2148. thisamp = (float)(VOLUME_PAD/(double)dz->clength);
  2149. if(dz->process==P_SYNTH) {
  2150. dz->wanted = dz->clength * 2;
  2151. partials_in_test_tone = dz->itemcnt;
  2152. } else
  2153. partials_in_test_tone = PARTIALS_IN_TEST_TONE;
  2154. while(n < dz->wlength) {
  2155. done = FALSE;
  2156. thisfrq = dz->pitches[n];
  2157. if(thisfrq < 0.0){ /* NO PITCH FOUND : GENERATE NOISE */
  2158. if(thisfrq > NOT_SOUND) {
  2159. if(dz->process!=P_SYNTH)
  2160. thisamp = (float)((dz->parray[PICH_PRETOTAMP][n]/(double)dz->clength) * VOLUME_PAD);
  2161. basefrq = 0.0;
  2162. dz->flbufptr[0][1] = (float)(drand48() * dz->halfchwidth);
  2163. basefrq += dz->halfchwidth;
  2164. for(cc = 1, vc = 2; cc < dz->clength - 1; cc++, vc += 2) {
  2165. dz->flbufptr[0][FREQ] = (float)((drand48() * dz->chwidth) + basefrq);
  2166. dz->flbufptr[0][AMPP] = (float)(thisamp * ((drand48() * noisrange) + NOISEBASE));
  2167. basefrq += dz->chwidth;
  2168. }
  2169. dz->flbufptr[0][FREQ] = (float)(dz->nyquist - (drand48() * dz->halfchwidth));
  2170. dz->flbufptr[0][AMPP] = (float)(thisamp * ((drand48() * noisrange) + NOISEBASE));
  2171. done = TRUE;
  2172. } else {
  2173. basefrq = 0.0;
  2174. for(cc = 0, vc = 0; cc < dz->clength-1; cc++, vc += 2) {
  2175. dz->flbufptr[0][FREQ] = (float)basefrq;
  2176. dz->flbufptr[0][AMPP] = 0.0f;
  2177. basefrq += dz->chwidth;
  2178. }
  2179. dz->flbufptr[0][FREQ] = (float)dz->nyquist;
  2180. dz->flbufptr[0][AMPP] = 0.0f;
  2181. done = TRUE;
  2182. }
  2183. } else { /* GENERATE TESTTONE AT FOUND PITCH */
  2184. if(dz->process==P_SYNTH) {
  2185. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2)
  2186. dz->flbufptr[0][AMPP] = 0.0f;
  2187. basefrq = thisfrq;
  2188. totamp = 0.0;
  2189. for(m=0;m<partials_in_test_tone;m++) {
  2190. cc = (int)((thisfrq + dz->halfchwidth)/dz->chwidth);
  2191. vc = cc * 2;
  2192. if((level = dz->parray[PICH_SPEC][m]) > 0.0) {
  2193. dz->flbufptr[0][AMPP] = (float)level;
  2194. dz->flbufptr[0][FREQ] = (float)thisfrq;
  2195. totamp += dz->flbufptr[0][AMPP];
  2196. }
  2197. if((thisfrq += basefrq) > dz->nyquist) {
  2198. if((exit_status = normalise(VOLUME_PAD,totamp,dz))<0)
  2199. return(exit_status);
  2200. done = TRUE;
  2201. break;
  2202. }
  2203. }
  2204. } else {
  2205. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2)
  2206. dz->flbufptr[0][AMPP] = 0.0f;
  2207. for(m=0;m<partials_in_test_tone;m++) {
  2208. cc = (int)((thisfrq + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */
  2209. vc = cc * 2;
  2210. dz->flbufptr[0][AMPP] = dz->windowbuf[TESTPAMP][m];
  2211. dz->flbufptr[0][FREQ] = (float)thisfrq;
  2212. if((thisfrq = thisfrq * 2.0) > dz->nyquist) {
  2213. if((exit_status = normalise(dz->parray[PICH_PRETOTAMP][n] * VOLUME_PAD,
  2214. dz->windowbuf[TOTPAMP][m],dz))<0)
  2215. return(exit_status);
  2216. done = TRUE;
  2217. break;
  2218. }
  2219. }
  2220. }
  2221. }
  2222. if(!done) {
  2223. last_partial = partials_in_test_tone-1;
  2224. if(dz->process==P_SYNTH) {
  2225. if((level = dz->parray[PICH_SPEC][last_partial]) > 0.0) {
  2226. if((exit_status = normalise(VOLUME_PAD,totamp,dz))<0)
  2227. return(exit_status);
  2228. }
  2229. } else {
  2230. if((exit_status = normalise(dz->parray[PICH_PRETOTAMP][n],
  2231. dz->windowbuf[TOTPAMP][last_partial],dz))<0)
  2232. return(exit_status);
  2233. }
  2234. }
  2235. if((dz->flbufptr[0] += dz->wanted) >= dz->flbufptr[1]) {
  2236. if((exit_status = write_samps(dz->bigfbuf,dz->big_fsize,dz))<0)
  2237. return(exit_status);
  2238. dz->flbufptr[0] = dz->bigfbuf;
  2239. }
  2240. n++;
  2241. }
  2242. if(dz->flbufptr[0] != dz->bigfbuf) {
  2243. if((exit_status = write_samps(dz->bigfbuf,dz->flbufptr[0] - dz->bigfbuf,dz))<0)
  2244. return(exit_status);
  2245. }
  2246. return(FINISHED);
  2247. }
  2248. /********************** ANTI_NOISE_SMOOTHING *********************/
  2249. /*RWD used in conditional test, so better as a real var:*/
  2250. static const int MIN_SMOOTH_SET = 3;
  2251. /*#define MIN_SMOOTH_SET (3)*/ /* minimum number of adjacent smooth pitches to imply true pitch present */
  2252. #define MAX_GLISRATE (16.0) /* Assumptions: pitch can't move faster than 16 octaves per sec: MAX_GLISRATE */
  2253. /* Possible movement from window-to-window = MAX_GLISRATE * dz->frametime */
  2254. int anti_noise_smoothing(int wlength,float *pitches,float frametime)
  2255. {
  2256. char *smooth;
  2257. double max_pglide;
  2258. int n;
  2259. if(MIN_SMOOTH_SET<3) {
  2260. sprintf(errstr,"Bad constant: MIN_SMOOTH_SET: anti_noise_smoothing()\n");
  2261. return(PROGRAM_ERROR);
  2262. }
  2263. if(wlength < MIN_SMOOTH_SET + 1)
  2264. return(FINISHED);
  2265. max_pglide = pow(2.0,MAX_GLISRATE * frametime);
  2266. if((smooth = (char *)malloc((size_t)wlength))==NULL) {
  2267. sprintf(errstr,"aINSUFFICIENT MEMORY for smoothing array.\n");
  2268. return(MEMORY_ERROR);
  2269. }
  2270. for(n=1;n<wlength-1;n++)
  2271. smooth[n] = (char)is_smooth_from_both_sides(n,max_pglide,pitches);
  2272. smooth[0] = (char)is_initialpitch_smooth(smooth,max_pglide,pitches);
  2273. smooth[wlength-1] = (char)is_finalpitch_smooth(smooth,max_pglide,wlength,pitches);
  2274. for(n=MIN_SMOOTH_SET-1;n<wlength;n++) {
  2275. if(!smooth[n])
  2276. smooth[n] = (char)is_smooth_from_before(n,smooth,max_pglide,pitches);
  2277. }
  2278. for(n=0;n<=wlength-MIN_SMOOTH_SET;n++) {
  2279. if(!smooth[n])
  2280. smooth[n] = (char)is_smooth_from_after(n,smooth,max_pglide,pitches);
  2281. }
  2282. test_glitch_sets(smooth,max_pglide,wlength,pitches);
  2283. remove_unsmooth_pitches(smooth,wlength,pitches);
  2284. free(smooth);
  2285. return(FINISHED);
  2286. }
  2287. /********************** IS_SMOOTH_FROM_BOTH_SIDES *********************
  2288. *
  2289. * verify a pitch if it has continuity with the pitches on either side.
  2290. */
  2291. int is_smooth_from_both_sides(int n,double max_pglide,float *pitches)
  2292. {
  2293. float thispitch, pitch_before, pitch_after;
  2294. double pre_interval, post_interval;
  2295. if((thispitch = pitches[n]) < FLTERR)
  2296. return FALSE;
  2297. if((pitch_before = pitches[n-1]) < FLTERR)
  2298. return FALSE;
  2299. if((pitch_after = pitches[n+1]) < FLTERR)
  2300. return FALSE;
  2301. pre_interval = pitch_before/thispitch;
  2302. if(pre_interval < 1.0)
  2303. pre_interval = 1.0/pre_interval;
  2304. post_interval = pitch_after/thispitch;
  2305. if(post_interval < 1.0)
  2306. post_interval = 1.0/post_interval;
  2307. if(pre_interval > max_pglide
  2308. || post_interval > max_pglide)
  2309. return FALSE;
  2310. return TRUE;
  2311. }
  2312. /********************** IS_INITIALPITCH_SMOOTH *********************
  2313. *
  2314. * verify first pitch if it has continuity with an ensuing verified pitch.
  2315. */
  2316. int is_initialpitch_smooth(char *smooth,double max_pglide,float *pitches)
  2317. {
  2318. float thispitch;
  2319. int n;
  2320. double post_interval;
  2321. if((thispitch = pitches[0]) < FLTERR)
  2322. return FALSE;
  2323. for(n=1;n < MIN_SMOOTH_SET;n++) {
  2324. if(smooth[n]) {
  2325. post_interval = pitches[n]/pitches[0];
  2326. if(post_interval < 1.0)
  2327. post_interval = 1.0/post_interval;
  2328. if(post_interval <= pow(max_pglide,(double)n))
  2329. return TRUE;
  2330. }
  2331. }
  2332. return(FALSE);
  2333. }
  2334. /********************** IS_FINALPITCH_SMOOTH *********************
  2335. *
  2336. * verify final pitch if it has continuity with a preceding verified pitch.
  2337. */
  2338. int is_finalpitch_smooth(char *smooth,double max_pglide,int wlength,float *pitches)
  2339. {
  2340. float thispitch;
  2341. double pre_interval;
  2342. int n;
  2343. int last = wlength - 1;
  2344. if((thispitch = pitches[last]) < FLTERR)
  2345. return FALSE;
  2346. for(n=1;n < MIN_SMOOTH_SET;n++) {
  2347. if(smooth[last-n]) {
  2348. pre_interval = pitches[last-n]/pitches[last];
  2349. if(pre_interval < 1.0)
  2350. pre_interval = 1.0/pre_interval;
  2351. if(pre_interval <= pow(max_pglide,(double)n))
  2352. return TRUE;
  2353. }
  2354. }
  2355. return(FALSE);
  2356. }
  2357. /********************** IS_SMOOTH_FROM_BEFORE *********************
  2358. *
  2359. * verify a pitch which has continuity with a preceding set of verified pitches.
  2360. */
  2361. int is_smooth_from_before(int n,char *smooth,double max_pglide,float *pitches)
  2362. {
  2363. float thispitch, pitch_before;
  2364. double pre_interval;
  2365. int m;
  2366. if((thispitch = pitches[n]) < FLTERR)
  2367. return FALSE;
  2368. for(m=1;m<MIN_SMOOTH_SET;m++) { /* If there are (MIN_SMOOTH_SET-1) smooth pitches before */
  2369. if(!smooth[n-m])
  2370. return(FALSE);
  2371. }
  2372. pitch_before = pitches[n-1]; /* Test the interval with the previous pitch */
  2373. pre_interval = pitch_before/thispitch;
  2374. if(pre_interval < 1.0)
  2375. pre_interval = 1.0/pre_interval;
  2376. if(pre_interval > max_pglide)
  2377. return FALSE; /* And if it's acceptably smooth */
  2378. return TRUE; /* mark this pitch as smooth also */
  2379. }
  2380. /********************** IS_SMOOTH_FROM_AFTER *********************
  2381. *
  2382. * verify a pitch which has continuity with a following set of verified pitches.
  2383. */
  2384. int is_smooth_from_after(int n,char *smooth,double max_pglide,float *pitches)
  2385. {
  2386. float thispitch, pitch_after;
  2387. double post_interval;
  2388. int m;
  2389. if((thispitch = pitches[n]) < FLTERR)
  2390. return FALSE;
  2391. for(m=1;m<MIN_SMOOTH_SET;m++) { /* If there are (MIN_SMOOTH_SET-1) smooth pitches after */
  2392. if(!smooth[n+m])
  2393. return(FALSE);
  2394. }
  2395. pitch_after = pitches[n+1]; /* Test the interval with the next pitch */
  2396. post_interval = pitch_after/thispitch;
  2397. if(post_interval < 1.0)
  2398. post_interval = 1.0/post_interval;
  2399. if(post_interval > max_pglide)
  2400. return FALSE; /* And if it's acceptably smooth */
  2401. return TRUE; /* mark this pitch as smooth also */
  2402. }
  2403. /********************** TEST_GLITCH_SETS *********************
  2404. *
  2405. * This function looks for any sets of values that appear to be glitches
  2406. * amongst the real pitch data.
  2407. * It is possible some items are REAL pitch data isolated BETWEEN short glitches.
  2408. * This function checks for these cases.
  2409. */
  2410. int test_glitch_sets(char *smooth,double max_pglide,int wlength,float *pitches)
  2411. {
  2412. int exit_status;
  2413. int gotglitch = FALSE;
  2414. int n, gltchend, gltchstart = 0;
  2415. for(n=0;n<wlength;n++) {
  2416. if(gotglitch) { /* if inside a glitch */
  2417. if(smooth[n]) { /* if reached its end, mark the end, then process the glitch */
  2418. gltchend = n;
  2419. if((exit_status = test_glitch_forwards(gltchstart,gltchend,smooth,max_pglide,pitches))<0)
  2420. return(exit_status);
  2421. if((exit_status = test_glitch_backwards(gltchstart,gltchend,smooth,max_pglide,wlength,pitches))<0)
  2422. return(exit_status);
  2423. gotglitch = 0;
  2424. }
  2425. } else { /* look for a glitch and mark its start */
  2426. if(!smooth[n]) {
  2427. gotglitch = 1;
  2428. gltchstart = n;
  2429. }
  2430. }
  2431. }
  2432. if(gotglitch) { /* if inside a glitch at end of data, process glitch */
  2433. gltchend = n;
  2434. test_glitch_forwards(gltchstart,gltchend,smooth,max_pglide,pitches);
  2435. }
  2436. return(FINISHED);
  2437. }
  2438. /********************* REMOVE_UNSMOOTH_PITCHES ***********************
  2439. *
  2440. * delete all pitches which have no verified continuity with surrounding pitches.
  2441. */
  2442. void remove_unsmooth_pitches(char *smooth,int wlength,float *pitches)
  2443. {
  2444. int n;
  2445. for(n=0;n<wlength;n++) {
  2446. if(!smooth[n])
  2447. pitches[n] = (float)NOT_PITCH;
  2448. }
  2449. }
  2450. /********************** TEST_GLITCH_FORWARDS *********************
  2451. *
  2452. * searching from start of glitch, look for isolated true pitches
  2453. * amongst glitch data.
  2454. */
  2455. #define LAST_SMOOTH_NOT_SET (-1)
  2456. int test_glitch_forwards(int gltchstart,int gltchend,char *smooth,double max_pglide,float *pitches)
  2457. {
  2458. int n, glcnt;
  2459. int last_smooth, previous;
  2460. double pre_interval;
  2461. if((previous = gltchstart - 1) < 0)
  2462. return FINISHED;
  2463. if(pitches[previous] < FLTERR) {
  2464. sprintf(errstr,"Error in previous smoothing logic: test_glitch_forwards()\n");
  2465. return(PROGRAM_ERROR);
  2466. }
  2467. last_smooth = previous;
  2468. n = gltchstart+1; /* setup params for local search of glitch */
  2469. glcnt = 1;
  2470. while(n < gltchend) { /* look through the glitch */
  2471. if(pitches[n] > FLTERR) { /* if glitch location holds a true pitch */
  2472. pre_interval = pitches[n]/pitches[previous];
  2473. if(pre_interval < 1.0)
  2474. pre_interval = 1.0/pre_interval; /* compare against previous verified pitch */
  2475. if(pre_interval <= pow(max_pglide,(double)(n-previous))) {
  2476. smooth[n] = TRUE; /* if comparable: mark this pitch as verified */
  2477. last_smooth = n;
  2478. }
  2479. }
  2480. n++; /* Once more than a max-glitch-set has been scanned */
  2481. /* or the end of the entire glitch is reached */
  2482. if(++glcnt >= MIN_SMOOTH_SET || n >= gltchend) {
  2483. if(last_smooth == previous)
  2484. break; /* If no new verifiable pitch found, give up */
  2485. previous = last_smooth;
  2486. n = last_smooth + 1; /* Otherwise start a new local search from newly verified pitch */
  2487. glcnt = 1;
  2488. }
  2489. }
  2490. return(FINISHED);
  2491. }
  2492. /********************** TEST_GLITCH_BACKWARDS *********************
  2493. *
  2494. * searching from end of glitch, look for isolated true pitches
  2495. * amongst glitch data.
  2496. */
  2497. int test_glitch_backwards(int gltchstart,int gltchend,char *smooth,double max_pglide,int wlength,float *pitches)
  2498. {
  2499. int n, glcnt, next, next_smooth;
  2500. double post_interval;
  2501. if((next = gltchend) >= wlength)
  2502. return FINISHED;
  2503. if(pitches[next] < FLTERR) {
  2504. sprintf(errstr,"Error in previous smoothing logic: test_glitch_backwards()\n");
  2505. return(PROGRAM_ERROR);
  2506. }
  2507. next_smooth = next;
  2508. n = gltchend-2; /* setup params for local search of glitch */
  2509. glcnt = 1;
  2510. while(n >= gltchstart) { /* look through the glitch */
  2511. if(pitches[n] > FLTERR) { /* if glitch location holds a true pitch */
  2512. post_interval = pitches[n]/pitches[next];
  2513. if(post_interval < 1.0)
  2514. post_interval = 1.0/post_interval; /* compare against previous verified pitch */
  2515. if(post_interval <= pow(max_pglide,(double)(next - n))) {
  2516. smooth[n] = TRUE; /* if comparable: mark this pitch as verified */
  2517. next_smooth = n;
  2518. }
  2519. }
  2520. n--; /* Once more than a max-glitch-set has been scanned */
  2521. /* or the start of the entire glitch is reached */
  2522. if(++glcnt >= MIN_SMOOTH_SET || n < gltchstart) {
  2523. if(next_smooth == next)
  2524. break; /* If no new verifiable pitch found, give up */
  2525. next = next_smooth;
  2526. n = next_smooth - 1;
  2527. glcnt = 1; /* Otherwise start a new local search */
  2528. }
  2529. }
  2530. return(FINISHED);
  2531. }
  2532. /*********** WRITE_PITCH_OUTHEADER_FROM_ANALYSIS_INHEADER_TO_SECOND_OUTFILE **************
  2533. *
  2534. * Works for specpitch and spectrack: which write to 2nd datafile!!!
  2535. */
  2536. int write_pitch_outheader_from_analysis_inheader_to_second_outfile(int ofd,dataptr dz)
  2537. {
  2538. int exit_status;
  2539. int orig_process = dz->process_type;
  2540. int orig_outfiletype = dz->outfiletype;
  2541. int orig_chans = dz->infile->channels;
  2542. int orig_origchans = dz->infile->origchans;
  2543. dz->process_type = ANAL_TO_PITCH;
  2544. dz->outfiletype = PITCH_OUT;
  2545. dz->outfile->origchans = dz->infile->channels;
  2546. dz->outfile->channels = 1;
  2547. if((exit_status = headwrite(ofd,dz))<0)
  2548. return(exit_status);
  2549. /* restore orig values */
  2550. dz->process_type = orig_process;
  2551. dz->outfiletype = orig_outfiletype;
  2552. dz->outfile->origchans = orig_origchans;
  2553. dz->outfile->channels = orig_chans;
  2554. return(FINISHED);
  2555. }
  2556. /***************************** LOCAL_PEAK **************************/
  2557. int local_peak(int thiscc,double frq, float *thisbuf, dataptr dz)
  2558. {
  2559. int thisvc = thiscc * 2;
  2560. int cc, vc, searchtop, searchbot;
  2561. double frqtop = frq * SEMITONE_INTERVAL;
  2562. double frqbot = frq / SEMITONE_INTERVAL;
  2563. searchtop = (int)((frqtop + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */
  2564. searchtop = min(dz->clength,searchtop + PEAKSCAN + 1);
  2565. searchbot = (int)((frqbot + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */
  2566. searchbot = max(0,searchbot - PEAKSCAN);
  2567. for(cc = searchbot ,vc = searchbot*2; cc < searchtop; cc++, vc += 2) {
  2568. if(thisbuf[thisvc] < thisbuf[vc])
  2569. return(FALSE);
  2570. }
  2571. return(TRUE);
  2572. }
  2573. /**************************** INTERPOLATE_PITCH ***************************/
  2574. int interpolate_pitch(float *floatbuf,int skip_silence,dataptr dz)
  2575. {
  2576. int exit_status;
  2577. int pitchno;
  2578. for(pitchno=0;pitchno<dz->wlength;pitchno++) {
  2579. if(floatbuf[pitchno] < MINPITCH) {
  2580. if(skip_silence && flteq((double)floatbuf[pitchno],NOT_SOUND))
  2581. continue;
  2582. if((exit_status = do_interpolating(&pitchno,floatbuf,skip_silence,dz))<0)
  2583. return(exit_status);
  2584. }
  2585. }
  2586. return(FINISHED);
  2587. }
  2588. /****************************** DO_INTERPOLATING ************************
  2589. *
  2590. * WITHOUT THOROUGH CHECK, worried about logs getting <= 0.0.
  2591. */
  2592. int do_interpolating(int *pitchno,float *floatbuf,int skip_silence,dataptr dz)
  2593. {
  2594. #define MID_PITCH (0)
  2595. #define FIRST_PITCH (1)
  2596. #define END_PITCH (2)
  2597. #define NO_PITCH (3)
  2598. int act_type = MID_PITCH;
  2599. int start = *pitchno, m;
  2600. double startpitch, endpitch, thispitch, lastpitch, pstep;
  2601. if(*pitchno==0L)
  2602. act_type = FIRST_PITCH;
  2603. while(floatbuf[*pitchno] < MINPITCH) {
  2604. if(++(*pitchno)>=dz->wlength) {
  2605. if(act_type == FIRST_PITCH)
  2606. act_type = NO_PITCH;
  2607. else
  2608. act_type = END_PITCH;
  2609. break;
  2610. }
  2611. }
  2612. if(act_type==MID_PITCH) {
  2613. m = start-1;
  2614. while(floatbuf[m] < MINPITCH) {
  2615. if(--m <= 0) {
  2616. act_type = FIRST_PITCH;
  2617. break;
  2618. }
  2619. }
  2620. start = m;
  2621. }
  2622. switch(act_type) {
  2623. case(MID_PITCH):
  2624. startpitch = hz_to_pitchheight((double)floatbuf[start-1]);
  2625. endpitch = hz_to_pitchheight((double)floatbuf[*pitchno]);
  2626. pstep = (endpitch - startpitch)/(double)((*pitchno) - (start - 1));
  2627. lastpitch = startpitch;
  2628. for(m=start;m<*pitchno;m++) { /* INTERP PITCH ACROSS UNPITCHED SEG */
  2629. thispitch = lastpitch + pstep;
  2630. if(!(skip_silence && flteq(floatbuf[m],NOT_SOUND)))
  2631. floatbuf[m] = (float)pitchheight_to_hz(thispitch);
  2632. lastpitch = thispitch;
  2633. }
  2634. break;
  2635. case(FIRST_PITCH):
  2636. for(m=0;m<*pitchno;m++) { /* EXTEND FIRST CLEAR PITCH BACK TO START */
  2637. if(!(skip_silence && flteq(floatbuf[m],NOT_SOUND)))
  2638. floatbuf[m] = floatbuf[*pitchno];
  2639. }
  2640. break;
  2641. case(END_PITCH): /* EXTEND LAST CLEAR PITCH ON TO END */
  2642. for(m=start;m<*pitchno;m++) {
  2643. if(!(skip_silence && flteq(floatbuf[m],NOT_SOUND)))
  2644. floatbuf[m] = floatbuf[start-1];
  2645. }
  2646. break;
  2647. case(NO_PITCH):
  2648. sprintf(errstr,"No valid pitch found.\n");
  2649. return(GOAL_FAILED);
  2650. }
  2651. (*pitchno)--;
  2652. return(FINISHED);
  2653. }
  2654. /***************************** HZ_TO_PITCHHEIGHT *******************************
  2655. *
  2656. * Real pitch is 12 * log2(frq/basis_frq).
  2657. *
  2658. * BUT (with a little help from the Feynman lectures!!)
  2659. * (1) The basis_frq is arbitrary, and cancels out, so let it be 1.0.
  2660. i.e. pitch1 = 12 * log2(frq1/basis_frq) = 12 * (log2(frq1) - log2(basis_frq));
  2661. pitch2 = 12 * log2(frq2/basis_frq) = 12 * (log2(frq2) - log2(basis_frq));
  2662. pitch1 - pitch2 = 12 * (log2(frq1) - log2(frq2)) = 12 * log2(frq1/frq2);
  2663. * (2) Finding the difference of 2 log2() numbers, interpolating and
  2664. * reconverting to pow(2.0,...) is no different to doing same
  2665. * calculation to base e.
  2666. * (3) The (12 *) is also a cancellable factor in all this.
  2667. * So pitch_height serves the same function as pitch in these calculations!!
  2668. */
  2669. double hz_to_pitchheight(double frqq)
  2670. {
  2671. return log(frqq);
  2672. }
  2673. /***************************** PITCHHEIGHT_TO_HZ *******************************/
  2674. double pitchheight_to_hz(double pitch_height)
  2675. {
  2676. return exp(pitch_height);
  2677. }
  2678. /************************** ELIMINATE_BLIPS_IN_PITCH_DATA ****************************
  2679. *
  2680. * (1) Eliminate any group of 'dz->param[PICH_VALID]' pitched windows, bracketed by
  2681. * unpitched windows, as unreliable data.
  2682. */
  2683. int eliminate_blips_in_pitch_data(dataptr dz)
  2684. {
  2685. int q;
  2686. int n, m, k, wlength_less_bliplen;
  2687. int OK = 1;
  2688. switch(dz->process) {
  2689. case(PITCH): q = PICH_VALID; break;
  2690. case(TRACK): q = TRAK_VALID; break;
  2691. default:
  2692. sprintf(errstr,"unknown case in eliminate_blips_in_pitch_data()\n");
  2693. return(PROGRAM_ERROR);
  2694. }
  2695. if(dz->iparam[q]<=0)
  2696. return(FINISHED);
  2697. wlength_less_bliplen = dz->wlength - dz->iparam[q];
  2698. for(n=1;n<wlength_less_bliplen;n++) {
  2699. if(dz->pitches[n] > 0.0) {
  2700. if(dz->pitches[n-1] < 0.0) {
  2701. for(k = 1; k <= dz->iparam[q]; k++) {
  2702. if(dz->pitches[n+k] < 0.0) {
  2703. for(m=0;m<k;m++)
  2704. dz->pitches[n+m] = (float)NOT_PITCH;
  2705. n += k;
  2706. continue;
  2707. }
  2708. }
  2709. }
  2710. }
  2711. }
  2712. n = wlength_less_bliplen;
  2713. if((dz->pitches[n] > 0.0) && (dz->pitches[n-1] < 0.0)) {
  2714. /* UNREACHABLE at level4 ??? */
  2715. for(k = 1; k < dz->iparam[q]; k++) {
  2716. if(dz->pitches[n+k] < 0.0)
  2717. OK = 0;
  2718. break;
  2719. }
  2720. }
  2721. if(!OK) {
  2722. for(n=wlength_less_bliplen;n<dz->wlength;n++)
  2723. dz->pitches[n] = (float)NOT_PITCH;
  2724. }
  2725. return(FINISHED);
  2726. }
  2727. /********************************** MARK_ZEROS_IN_PITCHDATA ************************
  2728. *
  2729. * Disregard data on windows which are SILENCE_RATIO below maximum level.
  2730. */
  2731. int mark_zeros_in_pitchdata(dataptr dz)
  2732. {
  2733. int k;
  2734. int n;
  2735. double maxlevel = 0.0, minlevel;
  2736. switch(dz->process) {
  2737. case(PITCH): k = PICH_SRATIO; break;
  2738. case(TRACK): k = TRAK_SRATIO; break;
  2739. default:
  2740. sprintf(errstr,"unknown case in mark_zeros_in_pitchdata()\n");
  2741. return(PROGRAM_ERROR);
  2742. }
  2743. for(n=0;n<dz->wlength;n++) {
  2744. if(dz->parray[PICH_PRETOTAMP][n] > maxlevel)
  2745. maxlevel = dz->parray[PICH_PRETOTAMP][n];
  2746. }
  2747. minlevel = maxlevel * dz->param[k];
  2748. for(n=0;n<dz->wlength;n++) {
  2749. if(dz->parray[PICH_PRETOTAMP][n] < minlevel)
  2750. dz->pitches[n] = (float)NOT_SOUND;
  2751. }
  2752. return(FINISHED);
  2753. }
  2754. /**************************** PITCH_FOUND ****************************/
  2755. int pitch_found(dataptr dz)
  2756. {
  2757. int n;
  2758. for(n=0;n<dz->wlength;n++) {
  2759. if(dz->pitches[n] > NOT_PITCH)
  2760. return(FINISHED);
  2761. }
  2762. sprintf(errstr,"No valid pitch found.\n");
  2763. return(GOAL_FAILED);
  2764. }
  2765. /**************************** CHECK_TRANSPOS ****************************/
  2766. void check_transpos(float *t,dataptr dz)
  2767. {
  2768. if(*t <= MIN_TRANSPOS) {
  2769. if(!dz->fzeroset) {
  2770. fprintf(stdout,"WARNING: Transposition(s) by > max permitted: adjusted.\n");
  2771. fflush(stdout);
  2772. dz->fzeroset = TRUE;
  2773. }
  2774. *t = (float)(MIN_TRANSPOS + FLTERR);
  2775. }
  2776. if(*t >= MAX_TRANSPOS) {
  2777. if(!dz->fzeroset) {
  2778. fprintf(stdout,"WARNING: Transposition(s) by > max permitted: adjusted.\n");
  2779. fflush(stdout);
  2780. dz->fzeroset = TRUE;
  2781. }
  2782. *t = (float)(MAX_TRANSPOS - 1.0);
  2783. }
  2784. }
  2785. /**************************** CHECK_PITCH ****************************/
  2786. void check_pitch(float *t,dataptr dz)
  2787. {
  2788. if(*t <= SPEC_MINFRQ) {
  2789. if(!dz->fzeroset) {
  2790. fprintf(stdout,"WARNING: Pitch(es) out of permitted range: adjusted.\n");
  2791. fflush(stdout);
  2792. dz->fzeroset = TRUE;
  2793. }
  2794. *t = (float)(SPEC_MINFRQ + FLTERR);
  2795. }
  2796. if(*t >= DEFAULT_NYQUIST) {
  2797. if(!dz->fzeroset) {
  2798. fprintf(stdout,"WARNING: Pitch(es) out of permitted range: adjusted.\n");
  2799. fflush(stdout);
  2800. dz->fzeroset = TRUE;
  2801. }
  2802. *t = (float)(DEFAULT_NYQUIST-1.0);
  2803. }
  2804. }
  2805. /***************************** WRITE_PITCH_OR_TRANSPOS_DATA ******************************/
  2806. int write_pitch_or_transpos_data(int final_length_in_windows,dataptr dz)
  2807. {
  2808. int exit_status;
  2809. if(final_length_in_windows > 0) {
  2810. if(dz->is_transpos) {
  2811. if((exit_status = write_exact_samps(dz->transpos,final_length_in_windows,dz))<0)
  2812. return(exit_status);
  2813. } else {
  2814. if((exit_status = write_exact_samps(dz->pitches,final_length_in_windows,dz))<0)
  2815. return(exit_status);
  2816. }
  2817. }
  2818. return(FINISHED);
  2819. }
  2820. /***************************** TRAP_JUNK ******************************/
  2821. int trap_junk(int final_length_in_windows,dataptr dz)
  2822. {
  2823. int n;
  2824. int caught_zero = 0, caught_skrch = 0;
  2825. double mintrans, maxtrans;
  2826. if((dz->process==P_EXAG && ODD(dz->mode)) || dz->mode==TRANSP_OUT) {
  2827. /* Transposition file output */
  2828. maxtrans = dz->nyquist/MINPITCH;
  2829. mintrans = 1.0/maxtrans;
  2830. for(n=0;n<final_length_in_windows;n++) {
  2831. //if(!caught_zero && (dz->pitches[n] < mintrans && !flteq((double)dz->pitches[n],NOT_PITCH)))
  2832. // caught_zero = 1;
  2833. /*RWD 6:2001 */
  2834. if(!caught_zero && (dz->transpos[n] < mintrans && !
  2835. (flteq((double)dz->transpos[n],NOT_PITCH) || flteq((double)dz->transpos[n],NOT_SOUND))))
  2836. caught_zero = 1;
  2837. if(!caught_skrch && (dz->transpos[n] > maxtrans))
  2838. caught_skrch = 1;
  2839. if(caught_zero && caught_skrch)
  2840. break;
  2841. }
  2842. if(caught_zero || caught_skrch) {
  2843. if(caught_zero)
  2844. sprintf(errstr,"You have generated transposition data < the minimum possible.\n");
  2845. if(caught_skrch)
  2846. sprintf(errstr,"You have generated transposition data > the maximum possible.\n");
  2847. return(GOAL_FAILED);
  2848. }
  2849. } else { /* Pitch file output */
  2850. for(n=0;n<final_length_in_windows;n++) {
  2851. //if(!caught_zero && (dz->pitches[n] < MINPITCH && !flteq((double)dz->pitches[n],NOT_PITCH)))
  2852. // caught_zero = 1;
  2853. /* RWD 6:2001 trap zero windows too? */
  2854. if(!caught_zero && (dz->pitches[n] < MINPITCH && !
  2855. (flteq((double)dz->pitches[n],NOT_PITCH) || flteq((double)dz->pitches[n],NOT_SOUND))))
  2856. caught_zero = 1;
  2857. if(!caught_skrch && (dz->pitches[n] > dz->nyquist))
  2858. caught_skrch = 1;
  2859. if(caught_zero && caught_skrch)
  2860. break;
  2861. }
  2862. if(caught_zero || caught_skrch) {
  2863. if(caught_zero)
  2864. sprintf(errstr,"You have generated pitch data below %.0lfHz.\n",MINPITCH);
  2865. if(caught_skrch)
  2866. sprintf(errstr,"You have generated pitch data above the nyquist frq.\n");
  2867. return(GOAL_FAILED);
  2868. }
  2869. }
  2870. return(FINISHED);
  2871. }
  2872. int pitch_insert(int is_sil,dataptr dz)
  2873. {
  2874. int n, m, start, end;
  2875. int last_window = dz->wlength - 1;
  2876. int cnt = 0;
  2877. for(n=0;n<dz->itemcnt;n++) {
  2878. start = dz->lparray[0][n];
  2879. end = dz->lparray[1][n];
  2880. if(start > last_window)
  2881. break;
  2882. end = min(end,last_window);
  2883. if(is_sil) {
  2884. for(m=start;m<=end;m++) {
  2885. dz->pitches[m] = (float)NOT_SOUND;
  2886. cnt++;
  2887. }
  2888. } else {
  2889. for(m=start;m<=end;m++) {
  2890. dz->pitches[m] = (float)NOT_PITCH;
  2891. cnt++;
  2892. }
  2893. }
  2894. }
  2895. if(cnt==0) {
  2896. sprintf(errstr,"No insertions made.\n");
  2897. return(GOAL_FAILED);
  2898. }
  2899. return(FINISHED);
  2900. }
  2901. int pitch_to_silence(dataptr dz)
  2902. {
  2903. int n, cnt = 0;
  2904. for(n=0;n < dz->wlength;n++) {
  2905. if(!flteq((double)dz->pitches[n],NOT_PITCH)) {
  2906. dz->pitches[n] = (float)NOT_SOUND;
  2907. cnt++;
  2908. }
  2909. }
  2910. if(cnt==0) {
  2911. sprintf(errstr,"No silence inserted.\n");
  2912. return(GOAL_FAILED);
  2913. }
  2914. return(FINISHED);
  2915. }
  2916. int unpitch_to_silence(dataptr dz)
  2917. {
  2918. int n, cnt = 0;
  2919. for(n=0;n<dz->wlength;n++) {
  2920. if(flteq((double)dz->pitches[n],NOT_PITCH)) {
  2921. dz->pitches[n] = (float)NOT_SOUND;
  2922. cnt++;
  2923. }
  2924. }
  2925. if(cnt==0) {
  2926. sprintf(errstr,"No silence inserted.\n");
  2927. return(GOAL_FAILED);
  2928. }
  2929. return(FINISHED);
  2930. }
  2931. /***************************** GET_ANAL_ENVELOPE ***********************/
  2932. int get_anal_envelope(dataptr dz)
  2933. {
  2934. int exit_status;
  2935. int samps_read, wc, windows_in_buf, samps_left;
  2936. double totalamp;
  2937. dz->flbufptr[1] = dz->flbufptr[2];
  2938. while((samps_read = fgetfbufEx(dz->bigfbuf,dz->big_fsize,dz->ifd[0],0)) > 0) {
  2939. dz->flbufptr[0] = dz->bigfbuf;
  2940. windows_in_buf = samps_read/dz->wanted;
  2941. for(wc=0; wc<windows_in_buf; wc++) {
  2942. if((exit_status = get_totalamp(&totalamp,dz->flbufptr[0],dz->wanted))<0)
  2943. return(exit_status);
  2944. *(dz->flbufptr[1]) = (float)totalamp;
  2945. if(++dz->flbufptr[1] >= dz->flbufptr[3]) {
  2946. dz->flbufptr[1] = dz->flbufptr[2];
  2947. if((exit_status = write_samps(dz->flbufptr[2],dz->big_fsize,dz))<0)
  2948. return(exit_status);
  2949. }
  2950. dz->flbufptr[0] += dz->wanted;
  2951. }
  2952. }
  2953. if((samps_left = dz->flbufptr[1] - dz->flbufptr[2]) > 0) {
  2954. if((exit_status = write_samps(dz->flbufptr[2],samps_left,dz))<0)
  2955. return(exit_status);
  2956. }
  2957. dz->outfile->window_size = (float)(dz->frametime * SECS_TO_MS);
  2958. return(FINISHED);
  2959. }
  2960. /************************************ GENERATE_VOWELS ************************************/
  2961. int generate_vowels(dataptr dz)
  2962. {
  2963. int *vowels = dz->iparray[0];
  2964. double *times = dz->parray[0];
  2965. double startformant1, startformant2, startformant3, endformant1, endformant2, endformant3;
  2966. double formant1, formant2, formant3;
  2967. double form1step, form2step, form3step;
  2968. double starttime, endtime, time, timefrac, timestep, *sensitivity;
  2969. double thisfrq, basefrq;
  2970. double f3startatten, f3endatten, f3attenstep, f3atten;
  2971. double f2startatten, f2endatten, f2attenstep, f2atten;
  2972. float thisamp = (float)(VOLUME_PAD/(double)dz->clength);
  2973. double noisrange = 1.0 - NOISEBASE;
  2974. int cc, vc, exit_status, senslen, is_offset = 0;
  2975. int n = 0, t = 0;
  2976. if((exit_status = define_sensitivity_curve(&sensitivity,&senslen))<0)
  2977. return(exit_status);
  2978. if(dz->param[PV_OFFSET] > 0.0)
  2979. is_offset = 1;
  2980. dz->flbufptr[0] = dz->bigfbuf;
  2981. dz->wanted = dz->infile->origchans;
  2982. if((exit_status = get_formant_frqs
  2983. (vowels[t],&startformant1,&startformant2,&startformant3,&f2startatten,&f3startatten))<0)
  2984. return(exit_status);
  2985. starttime = times[t++];
  2986. if((exit_status = get_formant_frqs(vowels[t],&endformant1,&endformant2,&endformant3,&f2endatten,&f3endatten))<0)
  2987. return(exit_status);
  2988. endtime = times[t++];
  2989. form1step = endformant1 - startformant1;
  2990. form2step = endformant2 - startformant2;
  2991. form3step = endformant3 - startformant3;
  2992. f2attenstep = f2endatten - f2startatten;
  2993. f3attenstep = f3endatten - f3startatten;
  2994. timestep = endtime-starttime;
  2995. formant1 = startformant1; /* works if only one vowel is entered (for time zero) */
  2996. formant2 = startformant2;
  2997. formant3 = startformant3;
  2998. f2atten = f2startatten;
  2999. f3atten = f3startatten;
  3000. while(n < dz->wlength) {
  3001. thisfrq = dz->pitches[n];
  3002. if(thisfrq < 0.0){ /* NO PITCH FOUND : GENERATE NOISE */
  3003. if(thisfrq > NOT_SOUND) {
  3004. basefrq = 0.0;
  3005. dz->flbufptr[0][1] = (float)(drand48() * dz->halfchwidth);
  3006. basefrq += dz->halfchwidth;
  3007. for(cc = 1, vc = 2; cc < dz->clength - 1; cc++, vc += 2) {
  3008. dz->flbufptr[0][FREQ] = (float)((drand48() * dz->chwidth) + basefrq);
  3009. dz->flbufptr[0][AMPP] = (float)(thisamp * ((drand48() * noisrange) + NOISEBASE));
  3010. basefrq += dz->chwidth;
  3011. }
  3012. dz->flbufptr[0][FREQ] = (float)(dz->nyquist - (drand48() * dz->halfchwidth));
  3013. dz->flbufptr[0][AMPP] = (float)(thisamp * ((drand48() * noisrange) + NOISEBASE));
  3014. } else { /* NO SOUND FOUND, GENERATE SILENCE */
  3015. basefrq = 0.0;
  3016. for(cc = 0, vc = 0; cc < dz->clength-1; cc++, vc += 2) {
  3017. dz->flbufptr[0][FREQ] = (float)basefrq;
  3018. dz->flbufptr[0][AMPP] = 0.0f;
  3019. basefrq += dz->chwidth;
  3020. }
  3021. dz->flbufptr[0][FREQ] = (float)dz->nyquist;
  3022. dz->flbufptr[0][AMPP] = 0.0f;
  3023. }
  3024. } else { /* GENERATE VOWEL */
  3025. basefrq = 0.0;
  3026. for(cc = 0, vc = 0; cc < dz->clength-1; cc++, vc += 2) {
  3027. dz->flbufptr[0][AMPP] = 0.0f;
  3028. dz->flbufptr[0][FREQ] = (float)basefrq; /* default frq, overwritten by vowel partials */
  3029. basefrq += dz->chwidth;
  3030. }
  3031. dz->flbufptr[0][AMPP] = 0.0f;
  3032. dz->flbufptr[0][FREQ] = (float)dz->nyquist;
  3033. if(dz->itemcnt) {
  3034. time = n * dz->frametime;
  3035. while(time >= endtime) { /* advance along vowels */
  3036. startformant1 = endformant1;
  3037. startformant2 = endformant2;
  3038. startformant3 = endformant3;
  3039. f2startatten = f2endatten;
  3040. f3startatten = f3endatten;
  3041. starttime = endtime;
  3042. if(t < dz->itemcnt) {
  3043. if((exit_status = get_formant_frqs(vowels[t],&endformant1,&endformant2,&endformant3,&f2endatten,&f3endatten))<0)
  3044. return(exit_status);
  3045. endtime = times[t++];
  3046. } else
  3047. break;
  3048. form1step = endformant1 - startformant1;
  3049. form2step = endformant2 - startformant2;
  3050. form3step = endformant3 - startformant3;
  3051. f2attenstep = f2endatten - f2startatten;
  3052. f3attenstep = f3endatten - f3startatten;
  3053. timestep = endtime-starttime;
  3054. }
  3055. if(!flteq(starttime,endtime)) { /* interpolate between vowels : or retain last vowel */
  3056. timefrac = (time - starttime)/timestep;
  3057. formant1 = startformant1 + (form1step * timefrac);
  3058. formant2 = startformant2 + (form2step * timefrac);
  3059. formant3 = startformant3 + (form3step * timefrac);
  3060. f2atten = f2startatten + (f2attenstep * timefrac);
  3061. f3atten = f3startatten + (f3attenstep * timefrac);
  3062. }
  3063. }
  3064. if((exit_status = generate_vowel_spectrum
  3065. (thisfrq,formant1,formant2,formant3,f2atten,f3atten,sensitivity,senslen,is_offset,dz)) <0)
  3066. return(exit_status);
  3067. }
  3068. if((dz->flbufptr[0] += dz->wanted) >= dz->flbufptr[1]) {
  3069. if((exit_status = write_samps(dz->bigfbuf,dz->big_fsize,dz))<0)
  3070. return(exit_status);
  3071. dz->flbufptr[0] = dz->bigfbuf;
  3072. }
  3073. n++;
  3074. }
  3075. if(dz->flbufptr[0] != dz->bigfbuf) {
  3076. if((exit_status = write_samps(dz->bigfbuf,dz->flbufptr[0] - dz->bigfbuf,dz))<0)
  3077. return(exit_status);
  3078. }
  3079. return(FINISHED);
  3080. }
  3081. /************************************ DEFINE_SENSITIVITY_CURVE ************************************
  3082. *
  3083. * approximate compensation for aural sensitivity
  3084. */
  3085. #define LOFRQ_BOOST (2.511) /* 8dB */
  3086. #define HIFRQ_LOSS (0.4) /* -8dB */
  3087. #define LOFRQ_FOOT (250.0)
  3088. #define MIDFRQSHELF_BOT (2000.0)
  3089. #define MIDFRQSHELF_TOP (3000.0)
  3090. #define HIFRQ_FOOT (4000.0)
  3091. #define TOP_OF_SPECTRUM (96000.0) /* double maximum nyquist (i.e. >nyquist: for safety margin) */
  3092. int define_sensitivity_curve(double **sensitivity,int *senslen)
  3093. {
  3094. int arraysize = BIGARRAY;
  3095. double *p;
  3096. int n = 0;
  3097. if((*sensitivity = (double *)malloc(arraysize * sizeof(double)))==NULL) {
  3098. sprintf(errstr,"INSUFFICIENT MEMORY for time data.\n");
  3099. return(MEMORY_ERROR);
  3100. }
  3101. p = *sensitivity;
  3102. *p++ = 0.0; *p++ = 1.0; n+= 2; /* everything must be in 0-1 range */
  3103. *p++ = LOFRQ_FOOT; *p++ = 1.0; n+= 2; /* for pow() calculations to work, later */
  3104. *p++ = MIDFRQSHELF_BOT; *p++ = 1.0/LOFRQ_BOOST; n+= 2;
  3105. *p++ = MIDFRQSHELF_TOP; *p++ = 1.0/LOFRQ_BOOST; n+= 2;
  3106. *p++ = HIFRQ_FOOT; *p++ = HIFRQ_LOSS/LOFRQ_BOOST; n+= 2;
  3107. *p++ = TOP_OF_SPECTRUM; *p++ = HIFRQ_LOSS/LOFRQ_BOOST; n+= 2;
  3108. if((*sensitivity = (double *)realloc((char *)(*sensitivity),n * sizeof(double)))==NULL) {
  3109. sprintf(errstr,"INSUFFICIENT MEMORY for sensitivity curve.\n");
  3110. return(MEMORY_ERROR);
  3111. }
  3112. *senslen = n;
  3113. return(FINISHED);
  3114. }
  3115. /************************************ GET_FORMANT_FRQS ************************************/
  3116. int get_formant_frqs
  3117. (int vowel,double *formant1, double *formant2, double *formant3, double *f2atten, double *f3atten)
  3118. {
  3119. switch(vowel) {
  3120. case(VOWEL_EE): *formant1= EE_FORMANT1; *formant2= EE_FORMANT2; *formant3= EE_FORMANT3;
  3121. /* heed */ *f2atten = EE_F2ATTEN; *f3atten = EE_F3ATTEN;
  3122. break;
  3123. case(VOWEL_I): *formant1= I_FORMANT1; *formant2= I_FORMANT2; *formant3= I_FORMANT3;
  3124. /* hid */ *f2atten = I_F2ATTEN; *f3atten = I_F3ATTEN;
  3125. break;
  3126. case(VOWEL_AI): *formant1= AI_FORMANT1; *formant2= AI_FORMANT2; *formant3= AI_FORMANT3;
  3127. /* maid */ *f2atten = AI_F2ATTEN; *f3atten = AI_F3ATTEN;
  3128. break;
  3129. case(VOWEL_AII): *formant1= AII_FORMANT1; *formant2= AII_FORMANT2; *formant3= AII_FORMANT3;
  3130. /* scottish educAted */ *f2atten = AII_F2ATTEN; *f3atten = AII_F3ATTEN;
  3131. break;
  3132. case(VOWEL_E): *formant1= E_FORMANT1; *formant2= E_FORMANT2; *formant3= E_FORMANT3;
  3133. /* head */ *f2atten = E_F2ATTEN; *f3atten = E_F3ATTEN;
  3134. break;
  3135. case(VOWEL_A): *formant1= A_FORMANT1; *formant2= A_FORMANT2; *formant3= A_FORMANT3;
  3136. /* had */ *f2atten = A_F2ATTEN; *f3atten = A_F3ATTEN;
  3137. break;
  3138. case(VOWEL_AR): *formant1= AR_FORMANT1; *formant2= AR_FORMANT2; *formant3= AR_FORMANT3;
  3139. /* hard */ *f2atten = AR_F2ATTEN; *f3atten = AR_F3ATTEN;
  3140. break;
  3141. case(VOWEL_O): *formant1= O_FORMANT1; *formant2= O_FORMANT2; *formant3= O_FORMANT3;
  3142. /* hod */ *f2atten = O_F2ATTEN; *f3atten = O_F3ATTEN;
  3143. break;
  3144. case(VOWEL_OR): *formant1= OR_FORMANT1; *formant2= OR_FORMANT2; *formant3= OR_FORMANT3;
  3145. /* hoard */ *f2atten = OR_F2ATTEN; *f3atten = OR_F3ATTEN;
  3146. break;
  3147. case(VOWEL_OA): *formant1= OA_FORMANT1; *formant2= OA_FORMANT2; *formant3= OA_FORMANT3;
  3148. /* load (North of England) */ *f2atten = OA_F2ATTEN; *f3atten = OA_F3ATTEN;
  3149. break;
  3150. case(VOWEL_U): *formant1= U_FORMANT1; *formant2= U_FORMANT2; *formant3= U_FORMANT3;
  3151. /* hood, mud (Norht of England) */ *f2atten = U_F2ATTEN; *f3atten = U_F3ATTEN;
  3152. break;
  3153. case(VOWEL_UU): *formant1= UU_FORMANT1; *formant2= UU_FORMANT2; *formant3= UU_FORMANT3;
  3154. /* Scottish edUcated */ *f2atten = UU_F2ATTEN; *f3atten = UU_F3ATTEN;
  3155. break;
  3156. case(VOWEL_UI): *formant1= UI_FORMANT1; *formant2= UI_FORMANT2; *formant3= UI_FORMANT3;
  3157. /* Scottish 'could' */ *f2atten = UI_F2ATTEN; *f3atten = UI_F3ATTEN;
  3158. break;
  3159. case(VOWEL_OO): *formant1= OO_FORMANT1; *formant2= OO_FORMANT2; *formant3= OO_FORMANT3;
  3160. /* mood */ *f2atten = OO_F2ATTEN; *f3atten = OO_F3ATTEN;
  3161. break;
  3162. case(VOWEL_XX): *formant1= XX_FORMANT1; *formant2= XX_FORMANT2; *formant3= XX_FORMANT3;
  3163. /* mud (South of England) */ *f2atten = XX_F2ATTEN; *f3atten = XX_F3ATTEN;
  3164. break;
  3165. case(VOWEL_X): *formant1= X_FORMANT1; *formant2= X_FORMANT2; *formant3 = X_FORMANT3;
  3166. /* the, herd */ *f2atten = X_F2ATTEN; *f3atten = X_F3ATTEN;
  3167. break;
  3168. case(VOWEL_N): *formant1= N_FORMANT1; *formant2= N_FORMANT2; *formant3 = N_FORMANT3;
  3169. /* 'n' */ *f2atten = N_F2ATTEN; *f3atten = N_F3ATTEN;
  3170. break;
  3171. case(VOWEL_M): *formant1= M_FORMANT1; *formant2= M_FORMANT2; *formant3 = M_FORMANT3;
  3172. /* 'm' */ *f2atten = M_F2ATTEN; *f3atten = M_F3ATTEN;
  3173. break;
  3174. case(VOWEL_R): *formant1= R_FORMANT1; *formant2= R_FORMANT2; *formant3 = R_FORMANT3;
  3175. /* dRaws */ *f2atten = R_F2ATTEN; *f3atten = R_F3ATTEN;
  3176. break;
  3177. case(VOWEL_TH): *formant1= TH_FORMANT1; *formant2= TH_FORMANT2; *formant3 = TH_FORMANT3;
  3178. /* dRaws */ *f2atten = TH_F2ATTEN; *f3atten = TH_F3ATTEN;
  3179. break;
  3180. default:
  3181. sprintf(errstr,"Unknown vowel\n");
  3182. return(PROGRAM_ERROR);
  3183. }
  3184. return(FINISHED);
  3185. }
  3186. /************************************ GENERATE_VOWEL_SPECTRUM ************************************
  3187. *
  3188. * "sensitivity" compensates for frq sensitivity of ear at low end, and attenuates
  3189. * formant bamds above c3500.
  3190. */
  3191. int generate_vowel_spectrum(double frq,double formant1,double formant2,double formant3,double f2atten,double f3atten,
  3192. double *sensitivity,int senslen,int is_offset,dataptr dz)
  3193. {
  3194. double hfwidth1, hfwidth2, hfwidth3 = 0.0, lolim1, lolim2, lolim3 = 0.0, hilim1, hilim2, hilim3 = 0.0;
  3195. double basefrq = frq, harmfrq = basefrq, thisfrq = basefrq, frq_offset;
  3196. double amp, amp2 = 0.0, amp3 = 0.0, totamp = 0.0;
  3197. int exit_status, cc, vc;
  3198. int overlapped_formants12 = 0, overlapped_formants23 = 0, overlapped_formants13 = 0;
  3199. int is_overlap12, is_overlap23, is_overlap13;
  3200. double toplim;
  3201. int is_third_formant = 0;
  3202. double signal_base = 1.0 - dz->param[PV_PKRANG];
  3203. if(formant3 > 0.0)
  3204. is_third_formant = 1;
  3205. hfwidth1 = formant1 * dz->param[PV_HWIDTH]; /* set limits of formant bands */
  3206. lolim1 = formant1 - hfwidth1;
  3207. hilim1 = formant1 + hfwidth1;
  3208. hfwidth2 = formant2 * dz->param[PV_HWIDTH];
  3209. lolim2 = formant2 - hfwidth2;
  3210. hilim2 = formant2 + hfwidth2;
  3211. if(is_third_formant) {
  3212. hfwidth3 = formant3 * dz->param[PV_HWIDTH];
  3213. lolim3 = formant3 - hfwidth3;
  3214. hilim3 = formant3 + hfwidth3;
  3215. }
  3216. if(hilim1 > lolim2) /* deal with overlapping formants */
  3217. overlapped_formants12 = 1;
  3218. if(is_third_formant) {
  3219. if(hilim2 > lolim3)
  3220. overlapped_formants23 = 1;
  3221. if(hilim1 > lolim3)
  3222. overlapped_formants13 = 1;
  3223. }
  3224. if(is_third_formant)
  3225. toplim = hilim3;
  3226. else
  3227. toplim = hilim2;
  3228. while(thisfrq < toplim) {
  3229. amp = 0.0; /* amplitude will get signal_base * sensitivity */
  3230. is_overlap12 = 0;
  3231. is_overlap23 = 0;
  3232. is_overlap13 = 0;
  3233. if(thisfrq < lolim1) {
  3234. if(flteq(thisfrq,basefrq))
  3235. amp = dz->param[PV_FUNBAS];
  3236. } else if((thisfrq > lolim1) && (thisfrq < hilim1)) {
  3237. if(overlapped_formants12 && (thisfrq > lolim2)) {
  3238. is_overlap12 = 1;
  3239. if(thisfrq >= formant2)
  3240. amp2 = (hilim2 - thisfrq)/hfwidth2;
  3241. else
  3242. amp2 = (thisfrq - lolim2)/hfwidth2;
  3243. amp2 *= f2atten;
  3244. }
  3245. if(is_third_formant) {
  3246. if(overlapped_formants13 && (thisfrq > lolim3)) {
  3247. is_overlap13 = 1;
  3248. if(thisfrq >= formant3)
  3249. amp3 = (hilim3 - thisfrq)/hfwidth3;
  3250. else
  3251. amp3 = (thisfrq - lolim3)/hfwidth3;
  3252. amp3 *= f3atten;
  3253. }
  3254. }
  3255. if(thisfrq >= formant1)
  3256. amp = (hilim1 - thisfrq)/hfwidth1;
  3257. else
  3258. amp = (thisfrq - lolim1)/hfwidth1;
  3259. if(is_overlap12)
  3260. amp = max(amp,amp2);
  3261. if(is_third_formant && is_overlap13)
  3262. amp = max(amp,amp3);
  3263. } else if((thisfrq > lolim2) && (thisfrq < hilim2)) {
  3264. if(is_third_formant && overlapped_formants23 && (thisfrq > lolim3)) {
  3265. is_overlap23 = 1;
  3266. if(thisfrq >= formant3)
  3267. amp3 = (hilim3 - thisfrq)/hfwidth3;
  3268. else
  3269. amp3 = (thisfrq - lolim3)/hfwidth3;
  3270. amp3 *= f3atten;
  3271. }
  3272. if(thisfrq >= formant2)
  3273. amp = (hilim2 - thisfrq)/hfwidth2;
  3274. else
  3275. amp = (thisfrq - lolim2)/hfwidth2;
  3276. amp *= f2atten;
  3277. if(is_third_formant && is_overlap23)
  3278. amp = max(amp,amp3);
  3279. } else if(is_third_formant && (thisfrq > lolim3)) {
  3280. if(thisfrq >= formant3)
  3281. amp = (hilim3 - thisfrq)/hfwidth3;
  3282. else
  3283. amp = (thisfrq - lolim3)/hfwidth3;
  3284. amp *= f3atten;
  3285. }
  3286. amp = pow(amp,dz->param[PV_CURVIT]);
  3287. amp *= dz->param[PV_PKRANG];
  3288. amp += signal_base;
  3289. if((exit_status = adjust_for_sensitivity(&amp,(double)thisfrq,sensitivity,senslen))<0)
  3290. return(exit_status);
  3291. cc = (int)((thisfrq + dz->halfchwidth)/dz->chwidth);
  3292. vc = cc * 2;
  3293. dz->flbufptr[0][AMPP] = (float)amp;
  3294. dz->flbufptr[0][FREQ] = (float)thisfrq;
  3295. totamp += amp;
  3296. if(is_offset) {
  3297. harmfrq += basefrq;
  3298. frq_offset = (drand48() - .5) * dz->param[PV_OFFSET] * basefrq;
  3299. if(harmfrq + frq_offset > dz->nyquist)
  3300. thisfrq = harmfrq - frq_offset;
  3301. else
  3302. thisfrq = harmfrq + frq_offset;
  3303. } else
  3304. thisfrq += basefrq;
  3305. if(thisfrq > dz->nyquist) {
  3306. sprintf(errstr,"Error in setting formant: overran nyquist\n");
  3307. return(PROGRAM_ERROR);
  3308. }
  3309. }
  3310. if((exit_status = normalise(VOLUME_PAD,totamp,dz))<0)
  3311. return(exit_status);
  3312. return(FINISHED);
  3313. }
  3314. /************************************ ADJUST_FOR_SENSITIVITY ************************************/
  3315. int adjust_for_sensitivity(double *amp,double frq,double *sensitivity,int senslen)
  3316. {
  3317. int n = 0;
  3318. double multiplier, losensfrq, hisensfrq, losens, hisens, frqfrac, sensstep;
  3319. while(frq > sensitivity[n]) {
  3320. n += 2;
  3321. if(n > senslen) {
  3322. sprintf(errstr,"Failed to find sensitivity value (1)\n");
  3323. return(PROGRAM_ERROR);
  3324. }
  3325. }
  3326. hisensfrq = sensitivity[n];
  3327. n -= 2;
  3328. if(n < 0) {
  3329. sprintf(errstr,"Failed to find sensitivity value (2)\n");
  3330. return(PROGRAM_ERROR);
  3331. }
  3332. losensfrq = sensitivity[n];
  3333. frqfrac = (frq - losensfrq)/(hisensfrq - losensfrq);
  3334. n++;
  3335. losens = sensitivity[n];
  3336. n += 2;
  3337. if(n >= senslen) {
  3338. sprintf(errstr,"Failed to find sensitivity value (3)\n");
  3339. return(PROGRAM_ERROR);
  3340. }
  3341. hisens = sensitivity[n];
  3342. sensstep = hisens - losens;
  3343. multiplier = losens + (sensstep * frqfrac);
  3344. * amp *= multiplier;
  3345. return(FINISHED);
  3346. }
  3347. /************************************ GENERATE_PITCH ************************************/
  3348. int generate_pitch(dataptr dz)
  3349. {
  3350. double *times = dz->parray[0];
  3351. double *pitch = dz->parray[1];
  3352. double startpitch, endpitch, pitchstep, thispitch;
  3353. double starttime, endtime, time, timefrac, timestep;
  3354. int n = 0, m = 0, samps_written;
  3355. if((dz->pitches = (float *)malloc(dz->wlength * sizeof(float)))==NULL) {
  3356. sprintf(errstr,"Insufficient memory to store pitch data\n");
  3357. return(MEMORY_ERROR);
  3358. }
  3359. starttime = times[m];
  3360. startpitch = pitch[m];
  3361. m++;
  3362. endtime = times[m];
  3363. endpitch = pitch[m];
  3364. m++;
  3365. pitchstep = endpitch - startpitch;
  3366. timestep = endtime - starttime;
  3367. while(n < dz->wlength) {
  3368. time = n * dz->frametime;
  3369. while(time >= endtime) { /* advance along (MIDI) pitches */
  3370. startpitch = endpitch;
  3371. starttime = endtime;
  3372. if(m < dz->itemcnt) {
  3373. endtime = times[m];
  3374. endpitch = pitch[m];
  3375. m++;
  3376. } else
  3377. break;
  3378. }
  3379. if(!flteq(starttime,endtime)) { /* interpolate between pitches : or retain last pitches */
  3380. pitchstep = endpitch - startpitch;
  3381. timestep = endtime - starttime;
  3382. timefrac = (time - starttime)/timestep;
  3383. thispitch = (pitchstep * timefrac) + startpitch;
  3384. } else
  3385. thispitch = startpitch;
  3386. dz->pitches[n++] = (float)miditohz(thispitch);
  3387. }
  3388. dz->is_transpos = 0;
  3389. return write_samps_no_report(dz->pitches,dz->wlength,&samps_written,dz);
  3390. }
  3391. /********************** REMOVE_PITCH_ZEROS *********************
  3392. *
  3393. * This function removes pitch zeroes (and si;ences) by interpolation.
  3394. */
  3395. int remove_pitch_zeros(dataptr dz)
  3396. {
  3397. int gotglitch = FALSE, gstart = -1;
  3398. double pstep, pstartval = 0.0;
  3399. int n, m;
  3400. for(n=0;n<dz->wlength;n++) {
  3401. if(gotglitch) {
  3402. if(dz->pitches[n] < MINPITCH)
  3403. continue;
  3404. if(gstart<0) {
  3405. for(m=0; m < n; m++) /* Interp to start if ness */
  3406. dz->pitches[m] = dz->pitches[n];
  3407. } else { /* Interp between good vals */
  3408. switch(dz->mode) {
  3409. case(PI_GLIDE):
  3410. pstep = (dz->pitches[n] - pstartval)/(double)(n - gstart);
  3411. for(m=gstart+1; m < n; m++) {
  3412. pstartval += pstep;
  3413. dz->pitches[m] = (float)pstartval;
  3414. }
  3415. break;
  3416. case(PI_SUSTAIN):
  3417. for(m=gstart+1; m < n; m++)
  3418. dz->pitches[m] = (float)pstartval;
  3419. break;
  3420. }
  3421. }
  3422. gotglitch = 0;
  3423. } else {
  3424. if(dz->pitches[n] >= MINPITCH)
  3425. continue;
  3426. gstart = n-1;
  3427. if(gstart >= 0)
  3428. pstartval = (double)dz->pitches[gstart];
  3429. gotglitch = 1;
  3430. }
  3431. }
  3432. if(gotglitch) {
  3433. if(gstart < 0) {
  3434. sprintf(errstr,"No pitched data found.");
  3435. return(GOAL_FAILED);
  3436. }
  3437. for(m=gstart+1; m < n; m++) /* Interp to end if ness */
  3438. dz->pitches[m] = (float)pstartval;
  3439. }
  3440. return(FINISHED);
  3441. }
  3442. /*************************** CONVERT_PITCH_FROM_BINARY_TO_TEXT **************************/
  3443. int convert_pitch_from_binary_to_text(dataptr dz)
  3444. {
  3445. int exit_status;
  3446. int brklen, n, m;
  3447. if((dz->parray[0] = malloc(((dz->wlength + 1) * 2) * sizeof(double)))==NULL) {
  3448. sprintf(errstr,"INSUFFICIENT MEMORY FOR TEXT DATA\n");
  3449. return MEMORY_ERROR;
  3450. }
  3451. if((exit_status = interpolate_pitch(dz->pitches,0,dz))<0)
  3452. return(exit_status);
  3453. if(dz->wlength == 1) {
  3454. if((exit_status = convert_single_window_pch_or_transpos_data_to_brkpnttable(&brklen,dz->pitches,dz->frametime,0,dz))<0)
  3455. return(exit_status);
  3456. } else {
  3457. if((exit_status = convert_pch_or_transpos_data_to_brkpnttable(&brklen,dz->pitches,dz->frametime,0,dz))<0)
  3458. return(exit_status);
  3459. }
  3460. for(n=0,m=0;n<brklen;n++,m+=2)
  3461. fprintf(dz->fp,"%lf\t%lf\n",dz->parray[0][m],dz->parray[0][m+1]);
  3462. return(FINISHED);
  3463. }
  3464. /***************** CONVERT_SINGLE_WINDOW_PCH_OR_TRANSPOS_DATA_TO_BRKPNTTABLE ***********************/
  3465. int convert_single_window_pch_or_transpos_data_to_brkpnttable(int *brksize,float *floatbuf,float frametime,int array_no,dataptr dz)
  3466. {
  3467. double *q;
  3468. float *p = floatbuf;
  3469. int bsize;
  3470. q = dz->parray[array_no];
  3471. *q++ = 0.0;
  3472. *q++ = (double)*p++;
  3473. bsize = q - dz->parray[array_no];
  3474. if((dz->parray[array_no] = (double *)realloc((char *)dz->parray[array_no],bsize*sizeof(double)))==NULL) {
  3475. sprintf(errstr,"convert_single_window_pch_or_transpos_data_to_brkpnttable()\n");
  3476. return(MEMORY_ERROR);
  3477. }
  3478. *brksize = bsize/2;
  3479. return(FINISHED);
  3480. }