spectrum.c 139 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092
  1. /*
  2. * Copyright (c) 1983-2023 Trevor Wishart and Composers Desktop Project Ltd
  3. * http://www.trevorwishart.co.uk
  4. * http://www.composersdesktop.com
  5. *
  6. This file is part of the CDP System.
  7. The CDP System is free software; you can redistribute it
  8. and/or modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  11. The CDP System is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU Lesser General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public
  16. License along with the CDP System; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18. 02111-1307 USA
  19. *
  20. */
  21. //In the middle of converting this to more general power.
  22. //Wee the new usage2 .....
  23. // SPEKPOINTS = param0 = ANALPOINTS in Loom interface
  24. // SPEKDUR = param1
  25. // definbed in science.h
  26. // #define SPEKSR 44100
  27. // #define SPEKPOINTS 0
  28. // #define SPEKSRATE 1
  29. // #define SPEKDUR 2
  30. // CONSIDER the data for SPECVARY having extra entries numbering the days(times) on which spectra measured??
  31. // so that the size of textdata files do not become huge (if data is interpd as text, will be much bigger!!)
  32. //
  33. // TO AVOID ARTEFACTS OF THE Channel-centre frqs
  34. // We need to generate frqs for the spectra that reflect something in the source (don't just use centre frq!!)
  35. /******************************** PROBLEM *******************
  36. //
  37. // !!!!!!!!!!!!! PROBLEM !!!!!!!!!!!!!!
  38. //
  39. // NEED A WAY TO DEAL WITH OVERLOAD - i.e. REDUCE SPECTRAL LEVEL !!!!!!
  40. */
  41. /*
  42. * NEW DEVELOPMENTS
  43. *
  44. * Data files have definite frq only for peaks and troughs ... other frqs 0.0
  45. * Other channels have -ve amps for troughs and +ve amps for peaks AND all others.
  46. *
  47. * Before C prog. Take the original data, and use a cubic-spline approach to find
  48. * true local maxima andminima with a resolution of 1/64th tone.
  49. *
  50. * Command line must now be
  51. *
  52. * spectrum fixed/variable outfile datafile chans srate dur [-hH] [-fF] [-rR] [-iI] [-zZ] [-gG] [-v]
  53. *
  54. * -h H = number of harmonics of peaks to have definite frqs
  55. * -f F = fraction of channels to be randomly varied (lower) than the amplitude curve value
  56. * -r R = max possible variation of selected chans (in F) from the amplitude curve value
  57. * -i I = proprtion of the bounding-curve to add to the inverted spectrum
  58. *
  59. * nb nb nb WHAT TO DO IF SPECTRUM IS NOT INVERTED .... whatval to give param, and how to give it!!!
  60. *
  61. *
  62. *
  63. * -z Z = rate at which frq is focused (zoomed) on apeak value, when spectrum changes from
  64. * one (pre-timeinterp) window to the next.
  65. * -g G = overallgain on output
  66. * -v Generate a text output suitable to view on screen.
  67. */
  68. #include <stdio.h>
  69. #include <stdlib.h>
  70. #include <structures.h>
  71. #include <tkglobals.h>
  72. #include <pnames.h>
  73. #include <filetype.h>
  74. #include <processno.h>
  75. #include <modeno.h>
  76. #include <logic.h>
  77. #include <globcon.h>
  78. #include <cdpmain.h>
  79. #include <math.h>
  80. #include <mixxcon.h>
  81. #include <osbind.h>
  82. #include <science.h>
  83. #include <ctype.h>
  84. #include <sfsys.h>
  85. #include <string.h>
  86. #include <srates.h>
  87. #include <standalone.h>
  88. //#ifdef unix
  89. #define round(x) lround((x))
  90. //#endif
  91. char errstr[2400];
  92. int anal_infiles = 0;
  93. int sloom = 0;
  94. int sloombatch = 0;
  95. const char* cdp_version = "7.1.0";
  96. //CDP LIB REPLACEMENTS
  97. static int check_spectrum_param_validity_and_consistency(int **perm,dataptr dz);
  98. static int setup_spectrum_application(dataptr dz);
  99. static int setup_spectrum_param_ranges_and_defaults(dataptr dz);
  100. static void init_specsynth(dataptr dz);
  101. static int allocate_spectrum_buffer(dataptr dz);
  102. static int specformat(dataptr dz);
  103. static int spectrum(int *perm,dataptr dz);
  104. static int specvary(dataptr dz);
  105. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  106. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz);
  107. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  108. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  109. static int establish_application(dataptr dz);
  110. static int initialise_vflags(dataptr dz);
  111. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  112. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  113. static int mark_parameter_types(dataptr dz,aplptr ap);
  114. static int assign_file_data_storage(int infilecnt,dataptr dz);
  115. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  116. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  117. static int handle_the_special_data(int *cmdlinecnt,char ***cmdline,dataptr dz);
  118. static int test_the_special_data(dataptr dz);
  119. static int open_the_outfile(dataptr dz);
  120. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  121. static void insert_harmonics(int **peaked,int *peakcnt,double harmamp,float fundamental,double pkwidth,dataptr dz);
  122. static void randomiseamps(int *perm,int *peaked,dataptr dz);
  123. static void rndintperm(int *perm,int cnt);
  124. static void spread_peaks(int *peaked,double spreaddnratio,double spreadupratio,dataptr dz);
  125. static int get_float_with_e_from_within_string(char **str,double *val);
  126. static int read_nearest_value_from_brktable(double thistime,int paramno,dataptr dz);
  127. static int check_spekline_param_validity_and_consistency(dataptr dz);
  128. static double dbtolevel(double val);
  129. static int speclines(dataptr dz);
  130. static int get_the_mode_from_cmdline(char *str,dataptr dz);
  131. static int speclinesfilt(dataptr dz);
  132. //RWD 2025 zero error checking - will already have been done!
  133. static int checkchans4format(int chans, const char* fname);
  134. /**************************************** MAIN *********************************************/
  135. int main(int argc,char *argv[])
  136. {
  137. int exit_status, *perm = NULL;
  138. dataptr dz = NULL;
  139. char **cmdline;
  140. int cmdlinecnt;
  141. //aplptr ap;
  142. int is_launched = FALSE;
  143. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  144. fprintf(stdout,"%s\n",cdp_version);
  145. fflush(stdout);
  146. return 0;
  147. }
  148. /* CHECK FOR SOUNDLOOM */
  149. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  150. sloom = 0;
  151. sloombatch = 1;
  152. }
  153. if(sflinit("cdp")){
  154. sfperror("cdp: initialisation\n");
  155. return(FAILED);
  156. }
  157. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  158. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  159. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  160. return(FAILED);
  161. }
  162. if(!sloom) {
  163. if(argc == 1) {
  164. usage1();
  165. return(FAILED);
  166. } else if(argc == 2) {
  167. usage2(argv[1]);
  168. return(FAILED);
  169. }
  170. }
  171. if(!sloom) {
  172. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  173. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  174. return(FAILED);
  175. }
  176. cmdline = argv;
  177. cmdlinecnt = argc;
  178. if((get_the_process_no(argv[0],dz))<0)
  179. return(FAILED);
  180. cmdline++;
  181. cmdlinecnt--;
  182. if(dz->process == SPEKLINE) {
  183. dz->maxmode = 2;
  184. if((exit_status = get_the_mode_from_cmdline(cmdline[0],dz))<0) {
  185. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  186. return(exit_status);
  187. }
  188. cmdline++;
  189. cmdlinecnt--;
  190. } else
  191. dz->maxmode = 0;
  192. // setup_particular_application =
  193. if((exit_status = setup_spectrum_application(dz))<0) {
  194. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  195. return(FAILED);
  196. }
  197. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  198. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  199. return(FAILED);
  200. }
  201. } else {
  202. //parse_TK_data() =
  203. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  204. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  205. return(exit_status);
  206. }
  207. }
  208. //ap = dz->application;
  209. // setup_param_ranges_and_defaults() =
  210. if((exit_status = setup_spectrum_param_ranges_and_defaults(dz))<0) {
  211. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  212. return(FAILED);
  213. }
  214. // handle_outfile() =
  215. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,dz))<0) {
  216. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  217. return(FAILED);
  218. }
  219. if((exit_status = handle_the_special_data(&cmdlinecnt,&cmdline,dz))<0) {
  220. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  221. return(FAILED);
  222. }
  223. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  224. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  225. return(FAILED);
  226. }
  227. // check_param_validity_and_consistency....
  228. if((exit_status = check_spectrum_param_validity_and_consistency(&perm,dz))<0) {
  229. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  230. return(FAILED);
  231. }
  232. if(dz->process == SPEKLINE) {
  233. if(dz->mode == 0)
  234. init_specsynth(dz);
  235. else
  236. dz->nyquist = dz->iparam[SPEKSRATE]/2.0;
  237. } else {
  238. if(dz->process != SPEKFRMT)
  239. // set up all spectrum params
  240. init_specsynth(dz);
  241. else
  242. dz->nyquist = dz->iparam[SPEKSRATE]/2.0;
  243. }
  244. if((exit_status = test_the_special_data(dz))<0) {
  245. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  246. return(FAILED);
  247. }
  248. is_launched = TRUE;
  249. if((exit_status = open_the_outfile(dz))<0) {
  250. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  251. return(FAILED);
  252. }
  253. if(dz->process != SPEKFRMT) {
  254. if((exit_status = allocate_spectrum_buffer(dz))<0) { // CDP LIB
  255. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  256. return(FAILED);
  257. }
  258. }
  259. if(dz->process == SPEKLINE) {
  260. if((exit_status = check_spekline_param_validity_and_consistency(dz))<0) {
  261. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  262. return(FAILED);
  263. }
  264. } else
  265. srand(1);
  266. switch(dz->process) {
  267. case(SPEKFRMT):
  268. if((exit_status = specformat(dz))<0) {
  269. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  270. return(FAILED);
  271. }
  272. break;
  273. case(SPEKTRUM):
  274. if((exit_status = spectrum(perm,dz))<0) {
  275. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  276. return(FAILED);
  277. }
  278. break;
  279. case(SPEKVARY):
  280. if((exit_status = specvary(dz))<0) {
  281. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  282. return(FAILED);
  283. }
  284. break;
  285. case(SPEKLINE):
  286. if(dz->mode == 0) {
  287. if((exit_status = speclines(dz))<0) {
  288. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  289. return(FAILED);
  290. }
  291. } else {
  292. if((exit_status = speclinesfilt(dz))<0) {
  293. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  294. return(FAILED);
  295. }
  296. }
  297. break;
  298. }
  299. if((exit_status = complete_output(dz))<0) { // CDP LIB
  300. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  301. return(FAILED);
  302. }
  303. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  304. free(dz);
  305. return(SUCCEEDED);
  306. }
  307. /**********************************************
  308. REPLACED CDP LIB FUNCTIONS
  309. **********************************************/
  310. /****************************** SET_PARAM_DATA *********************************/
  311. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  312. {
  313. ap->special_data = (char)special_data;
  314. ap->param_cnt = (char)paramcnt;
  315. ap->max_param_cnt = (char)maxparamcnt;
  316. if(ap->max_param_cnt>0) {
  317. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  318. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  319. // if(!sloom)
  320. // fprintf(stderr,errstr);
  321. return(MEMORY_ERROR);
  322. }
  323. strcpy(ap->param_list,paramlist);
  324. }
  325. return(FINISHED);
  326. }
  327. /****************************** SET_VFLGS *********************************/
  328. int set_vflgs
  329. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  330. {
  331. ap->option_cnt = (char) optcnt; /*RWD added cast */
  332. if(optcnt) {
  333. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  334. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  335. // if(!sloom)
  336. // fprintf(stderr,errstr);
  337. return(MEMORY_ERROR);
  338. }
  339. strcpy(ap->option_list,optlist);
  340. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  341. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  342. // if(!sloom)
  343. // fprintf(stderr,errstr);
  344. return(MEMORY_ERROR);
  345. }
  346. strcpy(ap->option_flags,optflags);
  347. }
  348. ap->vflag_cnt = (char) vflagcnt;
  349. ap->variant_param_cnt = (char) vparamcnt;
  350. if(vflagcnt) {
  351. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  352. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  353. // if(!sloom)
  354. // fprintf(stderr,errstr);
  355. return(MEMORY_ERROR);
  356. }
  357. strcpy(ap->variant_list,varlist);
  358. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  359. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  360. // if(!sloom)
  361. // fprintf(stderr,errstr);
  362. return(MEMORY_ERROR);
  363. }
  364. strcpy(ap->variant_flags,varflags);
  365. }
  366. return(FINISHED);
  367. }
  368. /***************************** APPLICATION_INIT **************************/
  369. int application_init(dataptr dz)
  370. {
  371. int exit_status;
  372. int storage_cnt;
  373. int tipc, brkcnt;
  374. aplptr ap = dz->application;
  375. if(ap->vflag_cnt>0)
  376. initialise_vflags(dz);
  377. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  378. ap->total_input_param_cnt = (char)tipc;
  379. if(tipc>0) {
  380. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  381. return(exit_status);
  382. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  383. return(exit_status);
  384. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  385. return(exit_status);
  386. }
  387. brkcnt = tipc;
  388. if(dz->input_data_type==UNRANGED_BRKFILE_ONLY) {
  389. dz->extrabrkno = brkcnt;
  390. brkcnt++; /* create brktable poniter for param0, and use point to and read (parray) input data during process */
  391. } else
  392. brkcnt++;
  393. if(brkcnt>0) {
  394. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  395. return(exit_status);
  396. }
  397. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  398. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  399. return(exit_status);
  400. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  401. return(exit_status);
  402. }
  403. if((exit_status = mark_parameter_types(dz,ap))<0)
  404. return(exit_status);
  405. dz->infilecnt = 0;
  406. return(FINISHED);
  407. }
  408. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  409. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  410. {
  411. int n;
  412. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  413. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  414. // if(!sloom)
  415. // fprintf(stderr,errstr);
  416. return(MEMORY_ERROR);
  417. }
  418. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  419. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  420. // if(!sloom)
  421. // fprintf(stderr,errstr);
  422. return(MEMORY_ERROR);
  423. }
  424. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  425. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  426. // if(!sloom)
  427. // fprintf(stderr,errstr);
  428. return(MEMORY_ERROR);
  429. }
  430. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  431. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  432. // if(!sloom)
  433. // fprintf(stderr,errstr);
  434. return(MEMORY_ERROR);
  435. }
  436. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  437. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  438. // if(!sloom)
  439. // fprintf(stderr,errstr);
  440. return(MEMORY_ERROR);
  441. }
  442. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  443. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  444. // if(!sloom)
  445. // fprintf(stderr,errstr);
  446. return(MEMORY_ERROR);
  447. }
  448. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  449. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  450. // if(!sloom)
  451. // fprintf(stderr,errstr);
  452. return(MEMORY_ERROR);
  453. }
  454. for(n=0;n<brkcnt;n++) {
  455. dz->brk[n] = NULL;
  456. dz->brkptr[n] = NULL;
  457. dz->brkinit[n] = 0;
  458. dz->brksize[n] = 0;
  459. }
  460. return(FINISHED);
  461. }
  462. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  463. /* RWD mallo changed to calloc; helps debug verison run as release! */
  464. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  465. {
  466. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  467. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  468. // if(!sloom)
  469. // fprintf(stderr,errstr);
  470. return(MEMORY_ERROR);
  471. }
  472. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  473. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  474. // if(!sloom)
  475. // fprintf(stderr,errstr);
  476. return(MEMORY_ERROR);
  477. }
  478. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  479. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  480. // if(!sloom)
  481. // fprintf(stderr,errstr);
  482. return(MEMORY_ERROR);
  483. }
  484. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  485. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  486. // if(!sloom)
  487. // fprintf(stderr,errstr);
  488. return(MEMORY_ERROR);
  489. }
  490. return(FINISHED);
  491. }
  492. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  493. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  494. {
  495. int n;
  496. for(n=0;n<storage_cnt;n++) {
  497. dz->is_int[n] = (char)0;
  498. dz->no_brk[n] = (char)0;
  499. }
  500. return(FINISHED);
  501. }
  502. /***************************** MARK_PARAMETER_TYPES **************************/
  503. int mark_parameter_types(dataptr dz,aplptr ap)
  504. {
  505. int n, m; /* PARAMS */
  506. for(n=0;n<ap->max_param_cnt;n++) {
  507. switch(ap->param_list[n]) {
  508. case('0'): break; /* dz->is_active[n] = 0 is default */
  509. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  510. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  511. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  512. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  513. default:
  514. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  515. // if(!sloom)
  516. // fprintf(stderr,errstr);
  517. return(PROGRAM_ERROR);
  518. }
  519. } /* OPTIONS */
  520. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  521. switch(ap->option_list[n]) {
  522. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  523. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  524. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  525. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  526. default:
  527. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  528. // if(!sloom)
  529. // fprintf(stderr,errstr);
  530. return(PROGRAM_ERROR);
  531. }
  532. } /* VARIANTS */
  533. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  534. switch(ap->variant_list[n]) {
  535. case('0'): break;
  536. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  537. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  538. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  539. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  540. default:
  541. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  542. // if(!sloom)
  543. // fprintf(stderr,errstr);
  544. return(PROGRAM_ERROR);
  545. }
  546. } /* INTERNAL */
  547. for(n=0,
  548. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  549. switch(ap->internal_param_list[n]) {
  550. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  551. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  552. case('d'): dz->no_brk[m] = (char)1; break;
  553. default:
  554. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  555. // if(!sloom)
  556. // fprintf(stderr,errstr);
  557. return(PROGRAM_ERROR);
  558. }
  559. }
  560. return(FINISHED);
  561. }
  562. /************************ HANDLE_THE_OUTFILE *********************/
  563. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz)
  564. {
  565. char *filename = (*cmdline)[0];
  566. if(filename[0]=='-' && filename[1]=='f') {
  567. dz->floatsam_output = 1;
  568. dz->true_outfile_stype = SAMP_FLOAT;
  569. filename+= 2;
  570. }
  571. if(!sloom) {
  572. if(file_has_invalid_startchar(filename) || value_is_numeric(filename)) {
  573. sprintf(errstr,"Outfile name %s has invalid start character(s) or looks too much like a number.\n",filename);
  574. // if(!sloom)
  575. // fprintf(stderr,errstr);
  576. return(DATA_ERROR);
  577. }
  578. }
  579. strcpy(dz->outfilename,filename);
  580. (*cmdline)++;
  581. (*cmdlinecnt)--;
  582. return(FINISHED);
  583. }
  584. /************************ OPEN_THE_OUTFILE *********************/
  585. int open_the_outfile(dataptr dz)
  586. {
  587. int exit_status;
  588. if((exit_status = create_sized_outfile(dz->outfilename,dz))<0)
  589. return(exit_status);
  590. if(dz->process != SPEKFRMT && dz->process != SPEKLINE) {
  591. if(dz->vflag[0])
  592. dz->is_rectified = 1;
  593. else
  594. dz->is_rectified = 0;
  595. }
  596. return(FINISHED);
  597. }
  598. /***************************** ESTABLISH_APPLICATION **************************/
  599. int establish_application(dataptr dz)
  600. {
  601. aplptr ap;
  602. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  603. sprintf(errstr,"establish_application()\n");
  604. // if(!sloom)
  605. // fprintf(stderr,errstr);
  606. return(MEMORY_ERROR);
  607. }
  608. ap = dz->application;
  609. memset((char *)ap,0,sizeof(struct applic));
  610. return(FINISHED);
  611. }
  612. /************************* INITIALISE_VFLAGS *************************/
  613. int initialise_vflags(dataptr dz)
  614. {
  615. int n;
  616. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  617. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  618. // if(!sloom)
  619. // fprintf(stderr,errstr);
  620. return(MEMORY_ERROR);
  621. }
  622. for(n=0;n<dz->application->vflag_cnt;n++)
  623. dz->vflag[n] = FALSE;
  624. return FINISHED;
  625. }
  626. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  627. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  628. {
  629. int n;
  630. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  631. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  632. // if(!sloom)
  633. // fprintf(stderr,errstr);
  634. return(MEMORY_ERROR);
  635. }
  636. for(n=0;n<tipc;n++)
  637. ap->default_val[n] = 0.0;
  638. return(FINISHED);
  639. }
  640. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  641. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  642. {
  643. int n;
  644. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  645. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  646. // if(!sloom)
  647. // fprintf(stderr,errstr);
  648. return(MEMORY_ERROR);
  649. }
  650. for(n=0;n<tipc;n++)
  651. dz->is_active[n] = (char)0;
  652. return(FINISHED);
  653. }
  654. /************************* SETUP_SPECTRUM_APPLICATION *******************/
  655. int setup_spectrum_application(dataptr dz)
  656. {
  657. int exit_status;
  658. aplptr ap;
  659. if((exit_status = establish_application(dz))<0) // GLOBAL
  660. return(FAILED);
  661. ap = dz->application;
  662. // SEE parstruct FOR EXPLANATION of next 2 functions
  663. switch(dz->process) {
  664. case(SPEKTRUM):
  665. if((exit_status = set_param_data(ap,0 ,3,3,"iid"))<0)
  666. return(FAILED);
  667. if((exit_status = set_vflgs(ap,"hbfrsatwm",9,"idddddiDd","d",1,0,"0"))<0)
  668. return(FAILED);
  669. dz->input_data_type = NO_FILE_AT_ALL;
  670. dz->process_type = BIG_ANALFILE;
  671. dz->outfiletype = ANALFILE_OUT;
  672. break;
  673. case(SPEKVARY):
  674. if((exit_status = set_param_data(ap,0 ,3,3,"iid"))<0)
  675. return(FAILED);
  676. if((exit_status = set_vflgs(ap,"hbfrsatwmz",10,"idddddiDdd","d",1,0,"0"))<0)
  677. return(FAILED);
  678. dz->input_data_type = NO_FILE_AT_ALL;
  679. dz->process_type = BIG_ANALFILE;
  680. dz->outfiletype = ANALFILE_OUT;
  681. break;
  682. case(SPEKFRMT):
  683. if((exit_status = set_param_data(ap,0 ,2,2,"ii"))<0)
  684. return(FAILED);
  685. if((exit_status = set_vflgs(ap,"",0,"","a",1,0,"0"))<0)
  686. return(FAILED);
  687. dz->input_data_type = BRKFILES_ONLY;
  688. dz->process_type = TO_TEXTFILE;
  689. dz->outfiletype = TEXTFILE_OUT;
  690. break;
  691. case(SPEKLINE):
  692. if(dz->mode == 0) {
  693. if((exit_status = set_param_data(ap,SPEKLDATA,12,12,"iididddddddd"))<0)
  694. return(FAILED);
  695. } else {
  696. if((exit_status = set_param_data(ap,SPEKLDATA,12,8,"0id00dddd0dd"))<0)
  697. return(FAILED);
  698. }
  699. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  700. return(FAILED);
  701. dz->input_data_type = NO_FILE_AT_ALL;
  702. if(dz->mode == 0) {
  703. dz->process_type = BIG_ANALFILE;
  704. dz->outfiletype = ANALFILE_OUT;
  705. } else {
  706. dz->process_type = TO_TEXTFILE;
  707. dz->outfiletype = TEXTFILE_OUT;
  708. }
  709. break;
  710. }
  711. // set_legal_infile_structure -->
  712. dz->has_otherfile = FALSE;
  713. // assign_process_logic -->
  714. return application_init(dz); //GLOBAL
  715. }
  716. /************************* SETUP_SPECTRUM_PARAM_RANGES_AND_DEFAULTS *******************/
  717. int setup_spectrum_param_ranges_and_defaults(dataptr dz)
  718. {
  719. int exit_status;
  720. aplptr ap = dz->application;
  721. // set_param_ranges()
  722. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  723. // NB total_input_param_cnt is > 0 !!!
  724. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  725. return(FAILED);
  726. // get_param_ranges()
  727. if(dz->process != SPEKLINE || dz->mode != 0) {
  728. ap->lo[SPEKPOINTS] = 2;
  729. ap->hi[SPEKPOINTS] = 32768; // CHANNEL CNT // RWD 2025 was 16380
  730. ap->default_val[SPEKPOINTS] = 2048;
  731. }
  732. if(dz->process == SPEKLINE && dz->mode == 0) {
  733. ap->lo[SPEKPOINTS] = 2;
  734. ap->hi[SPEKPOINTS] = 32768; // CHANNEL CNT //RWD as above
  735. ap->default_val[SPEKPOINTS] = 2048;
  736. }
  737. ap->lo[SPEKSRATE] = 44100;
  738. ap->hi[SPEKSRATE] = 96000; // SRATE
  739. ap->default_val[SPEKSRATE] = 44100;
  740. ap->lo[SPEKDUR] = 0;
  741. ap->hi[SPEKDUR] = 32767; // DURATION
  742. ap->default_val[SPEKDUR] = 10;
  743. if(dz->process == SPEKLINE) {
  744. if(dz->mode == 0) {
  745. ap->lo[SPEKHARMS] = 0;
  746. ap->hi[SPEKHARMS] = 64; // (MAX) NO OF HARMONICS TO EMPHASIZE
  747. ap->default_val[SPEKHARMS] = 0;
  748. ap->lo[SPEKBRITE] = -96;
  749. ap->hi[SPEKBRITE] = 0; // BRIGHTNESS (RELATIVE LEVEL OF SUCCESSIVE HARMONICS)
  750. ap->default_val[SPEKBRITE] = 0;
  751. }
  752. ap->lo[SPEKDATLO] = 0; // Bottom of input data range
  753. ap->hi[SPEKDATLO] = 48000;
  754. ap->default_val[SPEKDATLO] = 0;
  755. ap->lo[SPEKDATHI] = 0; // Top of input data range
  756. ap->hi[SPEKDATHI] = 48000;
  757. ap->default_val[SPEKDATHI] = 22050;
  758. ap->lo[SPEKSPKLO] = 0; // Bottom of spectral data range
  759. ap->hi[SPEKSPKLO] = 48000;
  760. ap->default_val[SPEKSPKLO] = 0;
  761. ap->lo[SPEKSPKHI] = 0; // Top of spectral data range
  762. ap->hi[SPEKSPKHI] = 48000;
  763. ap->default_val[SPEKSPKHI] = 22050;
  764. if(dz->mode == 0) {
  765. ap->lo[SPEKMAX] = 0.001; // Maximum channel gain in output spectrum
  766. ap->hi[SPEKMAX] = 1;
  767. ap->default_val[SPEKMAX] = 1;
  768. }
  769. ap->lo[SPEKWARP] = 0.1; // Warping of input spectrum
  770. ap->hi[SPEKWARP] = 10;
  771. ap->default_val[SPEKWARP] = 1;
  772. ap->lo[SPEKAWARP] = 1; // Warping of input amplitudes
  773. ap->hi[SPEKAWARP] = 100;
  774. ap->default_val[SPEKAWARP] = 1;
  775. } else {
  776. if(dz->process != SPEKFRMT) {
  777. ap->lo[2] = 0.1;
  778. ap->hi[2] = 3600; // OUTPUT DURATION
  779. ap->default_val[2] = 10;
  780. ap->lo[SPEKHARMS] = 0;
  781. ap->hi[SPEKHARMS] = 64; // (MAX) NO OF HARMONICS TO EMPHASIZE
  782. ap->default_val[SPEKHARMS] = 0;
  783. ap->lo[SPEKBRITE] = 0;
  784. ap->hi[SPEKBRITE] = 1; // BRIGHTNESS (RELATIVE LEVEL OF SUCCESSIVE HARMONICS)
  785. ap->default_val[SPEKBRITE] = 0;
  786. ap->lo[SPEKRANDF] = 0.0;
  787. ap->hi[SPEKRANDF] = 1.0; // MAX PROPORTION OF NON-PEAK CHANS TO VARY AWAY FROM AMPLITUDE-CURVE
  788. ap->default_val[SPEKRANDF] = 0;
  789. ap->lo[SPEKRANDA] = 0.1;
  790. ap->hi[SPEKRANDA] = 1.0; // MAX RAND EXCURSION OF AMPLITUDE FROM AMPLITUDE CURVE (FOR SPECIFIED CHANS)
  791. ap->default_val[SPEKRANDA] = 0;
  792. ap->lo[SPEKSPRED] = 0;
  793. ap->hi[SPEKSPRED] = 0.1;
  794. ap->default_val[SPEKSPRED] = 0; // SPREAD OF SPECTRAL PEAKS
  795. ap->lo[SPEKGAIN] = 0.001;
  796. ap->hi[SPEKGAIN] = 1.0;
  797. ap->default_val[SPEKGAIN] = 1; // OVERALL GAIN APPLIED TO OUTPUT
  798. ap->lo[SPEKTYPE] = 0;
  799. ap->hi[SPEKTYPE] = 5;
  800. ap->default_val[SPEKTYPE] = 0; // TYPE OF DATA INTERPRETATION
  801. ap->lo[SPEKWIDTH] = 0.0;
  802. ap->hi[SPEKWIDTH] = 96000; // RESET LATER
  803. ap->default_val[SPEKWIDTH] = 0; // WIDTH (ASPECT RATIO) OF SPECTRAL PEAKS
  804. ap->lo[SPEKMXASP] = 0.0;
  805. ap->hi[SPEKMXASP] = 96000; // RESET LATER
  806. ap->default_val[SPEKMXASP] = 0; // MAXIMUM ASPECT RATIO
  807. if(dz->process == SPEKVARY) {
  808. ap->lo[SPEKZOOM] = 0.1;
  809. ap->hi[SPEKZOOM] = 10.0;
  810. ap->default_val[SPEKZOOM] = 1; // RATE OF ZOOMING IN ON NEW PEAKDATA
  811. }
  812. }
  813. }
  814. dz->maxmode = 0;
  815. if(!sloom)
  816. put_default_vals_in_all_params(dz);
  817. return(FINISHED);
  818. }
  819. /********************************* PARSE_SLOOM_DATA *********************************/
  820. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  821. {
  822. int exit_status;
  823. int cnt = 1, infilecnt;
  824. int filesize, insams, inbrksize;
  825. double dummy;
  826. int true_cnt = 0;
  827. //aplptr ap;
  828. while(cnt<=PRE_CMDLINE_DATACNT) {
  829. if(cnt > argc) {
  830. sprintf(errstr,"Insufficient data sent from TK\n");
  831. // if(!sloom)
  832. // fprintf(stderr,errstr);
  833. return(DATA_ERROR);
  834. }
  835. switch(cnt) {
  836. case(1):
  837. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  838. sprintf(errstr,"Cannot read process no. sent from TK\n");
  839. // if(!sloom)
  840. // fprintf(stderr,errstr);
  841. return(DATA_ERROR);
  842. }
  843. break;
  844. case(2):
  845. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  846. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  847. // if(!sloom)
  848. // fprintf(stderr,errstr);
  849. return(DATA_ERROR);
  850. }
  851. if(dz->mode > 0)
  852. dz->mode--;
  853. //setup_particular_application() =
  854. if((exit_status = setup_spectrum_application(dz))<0)
  855. return(exit_status);
  856. //ap = dz->application;
  857. break;
  858. case(3):
  859. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  860. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  861. // if(!sloom)
  862. // fprintf(stderr,errstr);
  863. return(DATA_ERROR);
  864. }
  865. if(infilecnt < 1) {
  866. true_cnt = cnt + 1;
  867. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  868. }
  869. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  870. return(exit_status);
  871. break;
  872. case(INPUT_FILETYPE+4):
  873. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  874. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  875. // if(!sloom)
  876. // fprintf(stderr,errstr);
  877. return(DATA_ERROR);
  878. }
  879. break;
  880. case(INPUT_FILESIZE+4):
  881. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  882. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  883. // if(!sloom)
  884. // fprintf(stderr,errstr);
  885. return(DATA_ERROR);
  886. }
  887. dz->insams[0] = filesize;
  888. break;
  889. case(INPUT_INSAMS+4):
  890. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  891. sprintf(errstr,"Cannot read insams sent from TK\n");
  892. // if(!sloom)
  893. // fprintf(stderr,errstr);
  894. return(DATA_ERROR);
  895. }
  896. dz->insams[0] = insams;
  897. break;
  898. case(INPUT_SRATE+4):
  899. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  900. sprintf(errstr,"Cannot read srate sent from TK\n");
  901. // if(!sloom)
  902. // fprintf(stderr,errstr);
  903. return(DATA_ERROR);
  904. }
  905. break;
  906. case(INPUT_CHANNELS+4):
  907. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  908. sprintf(errstr,"Cannot read channels sent from TK\n");
  909. // if(!sloom)
  910. // fprintf(stderr,errstr);
  911. return(DATA_ERROR);
  912. }
  913. break;
  914. case(INPUT_STYPE+4):
  915. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  916. sprintf(errstr,"Cannot read stype sent from TK\n");
  917. // if(!sloom)
  918. // fprintf(stderr,errstr);
  919. return(DATA_ERROR);
  920. }
  921. break;
  922. case(INPUT_ORIGSTYPE+4):
  923. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  924. sprintf(errstr,"Cannot read origstype sent from TK\n");
  925. // if(!sloom)
  926. // fprintf(stderr,errstr);
  927. return(DATA_ERROR);
  928. }
  929. break;
  930. case(INPUT_ORIGRATE+4):
  931. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  932. sprintf(errstr,"Cannot read origrate sent from TK\n");
  933. // if(!sloom)
  934. // fprintf(stderr,errstr);
  935. return(DATA_ERROR);
  936. }
  937. break;
  938. case(INPUT_MLEN+4):
  939. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  940. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  941. // if(!sloom)
  942. // fprintf(stderr,errstr);
  943. return(DATA_ERROR);
  944. }
  945. break;
  946. case(INPUT_DFAC+4):
  947. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  948. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  949. // if(!sloom)
  950. // fprintf(stderr,errstr);
  951. return(DATA_ERROR);
  952. }
  953. break;
  954. case(INPUT_ORIGCHANS+4):
  955. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  956. sprintf(errstr,"Cannot read origchans sent from TK\n");
  957. // if(!sloom)
  958. // fprintf(stderr,errstr);
  959. return(DATA_ERROR);
  960. }
  961. break;
  962. case(INPUT_SPECENVCNT+4):
  963. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  964. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  965. // if(!sloom)
  966. // fprintf(stderr,errstr);
  967. return(DATA_ERROR);
  968. }
  969. dz->specenvcnt = dz->infile->specenvcnt;
  970. break;
  971. case(INPUT_WANTED+4):
  972. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  973. sprintf(errstr,"Cannot read wanted sent from TK\n");
  974. // if(!sloom)
  975. // fprintf(stderr,errstr);
  976. return(DATA_ERROR);
  977. }
  978. break;
  979. case(INPUT_WLENGTH+4):
  980. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  981. sprintf(errstr,"Cannot read wlength sent from TK\n");
  982. // if(!sloom)
  983. // fprintf(stderr,errstr);
  984. return(DATA_ERROR);
  985. }
  986. break;
  987. case(INPUT_OUT_CHANS+4):
  988. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  989. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  990. // if(!sloom)
  991. // fprintf(stderr,errstr);
  992. return(DATA_ERROR);
  993. }
  994. break;
  995. /* RWD these chanegs to samps - tk will have to deal with that! */
  996. case(INPUT_DESCRIPTOR_BYTES+4):
  997. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  998. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  999. // if(!sloom)
  1000. // fprintf(stderr,errstr);
  1001. return(DATA_ERROR);
  1002. }
  1003. break;
  1004. case(INPUT_IS_TRANSPOS+4):
  1005. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  1006. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  1007. // if(!sloom)
  1008. // fprintf(stderr,errstr);
  1009. return(DATA_ERROR);
  1010. }
  1011. break;
  1012. case(INPUT_COULD_BE_TRANSPOS+4):
  1013. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  1014. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  1015. // if(!sloom)
  1016. // fprintf(stderr,errstr);
  1017. return(DATA_ERROR);
  1018. }
  1019. break;
  1020. case(INPUT_COULD_BE_PITCH+4):
  1021. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  1022. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  1023. // if(!sloom)
  1024. // fprintf(stderr,errstr);
  1025. return(DATA_ERROR);
  1026. }
  1027. break;
  1028. case(INPUT_DIFFERENT_SRATES+4):
  1029. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  1030. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  1031. // if(!sloom)
  1032. // fprintf(stderr,errstr);
  1033. return(DATA_ERROR);
  1034. }
  1035. break;
  1036. case(INPUT_DUPLICATE_SNDS+4):
  1037. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  1038. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  1039. // if(!sloom)
  1040. // fprintf(stderr,errstr);
  1041. return(DATA_ERROR);
  1042. }
  1043. break;
  1044. case(INPUT_BRKSIZE+4):
  1045. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  1046. sprintf(errstr,"Cannot read brksize sent from TK\n");
  1047. // if(!sloom)
  1048. // fprintf(stderr,errstr);
  1049. return(DATA_ERROR);
  1050. }
  1051. if(inbrksize > 0) {
  1052. switch(dz->input_data_type) {
  1053. case(WORDLIST_ONLY):
  1054. break;
  1055. case(PITCH_AND_PITCH):
  1056. case(PITCH_AND_TRANSPOS):
  1057. case(TRANSPOS_AND_TRANSPOS):
  1058. dz->tempsize = inbrksize;
  1059. break;
  1060. case(BRKFILES_ONLY):
  1061. case(UNRANGED_BRKFILE_ONLY):
  1062. case(DB_BRKFILES_ONLY):
  1063. case(ALL_FILES):
  1064. case(ANY_NUMBER_OF_ANY_FILES):
  1065. if(dz->extrabrkno < 0) {
  1066. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  1067. // if(!sloom)
  1068. // fprintf(stderr,errstr);
  1069. return(DATA_ERROR);
  1070. }
  1071. if(dz->brksize == NULL) {
  1072. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  1073. // if(!sloom)
  1074. // fprintf(stderr,errstr);
  1075. return(PROGRAM_ERROR);
  1076. }
  1077. dz->brksize[dz->extrabrkno] = inbrksize;
  1078. break;
  1079. default:
  1080. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",dz->input_data_type);
  1081. // if(!sloom)
  1082. // fprintf(stderr,errstr);
  1083. return(PROGRAM_ERROR);
  1084. }
  1085. break;
  1086. }
  1087. break;
  1088. case(INPUT_NUMSIZE+4):
  1089. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  1090. sprintf(errstr,"Cannot read numsize sent from TK\n");
  1091. // if(!sloom)
  1092. // fprintf(stderr,errstr);
  1093. return(DATA_ERROR);
  1094. }
  1095. break;
  1096. case(INPUT_LINECNT+4):
  1097. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  1098. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  1099. // if(!sloom)
  1100. // fprintf(stderr,errstr);
  1101. return(DATA_ERROR);
  1102. }
  1103. break;
  1104. case(INPUT_ALL_WORDS+4):
  1105. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  1106. sprintf(errstr,"Cannot read all_words sent from TK\n");
  1107. // if(!sloom)
  1108. // fprintf(stderr,errstr);
  1109. return(DATA_ERROR);
  1110. }
  1111. break;
  1112. case(INPUT_ARATE+4):
  1113. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  1114. sprintf(errstr,"Cannot read arate sent from TK\n");
  1115. // if(!sloom)
  1116. // fprintf(stderr,errstr);
  1117. return(DATA_ERROR);
  1118. }
  1119. break;
  1120. case(INPUT_FRAMETIME+4):
  1121. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  1122. sprintf(errstr,"Cannot read frametime sent from TK\n");
  1123. // if(!sloom)
  1124. // fprintf(stderr,errstr);
  1125. return(DATA_ERROR);
  1126. }
  1127. dz->frametime = (float)dummy;
  1128. break;
  1129. case(INPUT_WINDOW_SIZE+4):
  1130. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  1131. sprintf(errstr,"Cannot read window_size sent from TK\n");
  1132. // if(!sloom)
  1133. // fprintf(stderr,errstr);
  1134. return(DATA_ERROR);
  1135. }
  1136. break;
  1137. case(INPUT_NYQUIST+4):
  1138. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  1139. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  1140. // if(!sloom)
  1141. // fprintf(stderr,errstr);
  1142. return(DATA_ERROR);
  1143. }
  1144. break;
  1145. case(INPUT_DURATION+4):
  1146. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  1147. sprintf(errstr,"Cannot read duration sent from TK\n");
  1148. // if(!sloom)
  1149. // fprintf(stderr,errstr);
  1150. return(DATA_ERROR);
  1151. }
  1152. break;
  1153. case(INPUT_MINBRK+4):
  1154. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  1155. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  1156. // if(!sloom)
  1157. // fprintf(stderr,errstr);
  1158. return(DATA_ERROR);
  1159. }
  1160. break;
  1161. case(INPUT_MAXBRK+4):
  1162. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  1163. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  1164. // if(!sloom)
  1165. // fprintf(stderr,errstr);
  1166. return(DATA_ERROR);
  1167. }
  1168. break;
  1169. case(INPUT_MINNUM+4):
  1170. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  1171. sprintf(errstr,"Cannot read minnum sent from TK\n");
  1172. // if(!sloom)
  1173. // fprintf(stderr,errstr);
  1174. return(DATA_ERROR);
  1175. }
  1176. break;
  1177. case(INPUT_MAXNUM+4):
  1178. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  1179. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  1180. // if(!sloom)
  1181. // fprintf(stderr,errstr);
  1182. return(DATA_ERROR);
  1183. }
  1184. break;
  1185. default:
  1186. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  1187. // if(!sloom)
  1188. // fprintf(stderr,errstr);
  1189. return(PROGRAM_ERROR);
  1190. }
  1191. cnt++;
  1192. }
  1193. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  1194. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  1195. // if(!sloom)
  1196. // fprintf(stderr,errstr);
  1197. return(DATA_ERROR);
  1198. }
  1199. if(true_cnt)
  1200. cnt = true_cnt;
  1201. *cmdlinecnt = 0;
  1202. while(cnt < argc) {
  1203. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  1204. return(exit_status);
  1205. cnt++;
  1206. }
  1207. return(FINISHED);
  1208. }
  1209. /********************************* GET_TK_CMDLINE_WORD *********************************/
  1210. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  1211. {
  1212. if(*cmdlinecnt==0) {
  1213. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  1214. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  1215. // if(!sloom)
  1216. // fprintf(stderr,errstr);
  1217. return(MEMORY_ERROR);
  1218. }
  1219. } else {
  1220. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  1221. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  1222. // if(!sloom)
  1223. // fprintf(stderr,errstr);
  1224. return(MEMORY_ERROR);
  1225. }
  1226. }
  1227. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  1228. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  1229. // if(!sloom)
  1230. // fprintf(stderr,errstr);
  1231. return(MEMORY_ERROR);
  1232. }
  1233. strcpy((*cmdline)[*cmdlinecnt],q);
  1234. (*cmdlinecnt)++;
  1235. return(FINISHED);
  1236. }
  1237. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  1238. int assign_file_data_storage(int infilecnt,dataptr dz)
  1239. {
  1240. int exit_status;
  1241. int no_sndfile_system_files = FALSE;
  1242. dz->infilecnt = infilecnt;
  1243. if((exit_status = allocate_filespace(dz))<0)
  1244. return(exit_status);
  1245. if(no_sndfile_system_files)
  1246. dz->infilecnt = 0;
  1247. return(FINISHED);
  1248. }
  1249. /************************* redundant functions: to ensure libs compile OK *******************/
  1250. int assign_process_logic(dataptr dz)
  1251. {
  1252. return(FINISHED);
  1253. }
  1254. void set_legal_infile_structure(dataptr dz)
  1255. {}
  1256. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  1257. {
  1258. return(FINISHED);
  1259. }
  1260. int setup_internal_arrays_and_array_pointers(dataptr dz)
  1261. {
  1262. return(FINISHED);
  1263. }
  1264. int establish_bufptrs_and_extra_buffers(dataptr dz)
  1265. {
  1266. return(FINISHED);
  1267. }
  1268. int read_special_data(char *str,dataptr dz)
  1269. {
  1270. return(FINISHED);
  1271. }
  1272. int inner_loop
  1273. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  1274. {
  1275. return(FINISHED);
  1276. }
  1277. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1278. {
  1279. return(FINISHED);
  1280. }
  1281. /******************************** USAGE1 ********************************/
  1282. int usage1(void)
  1283. {
  1284. fprintf(stderr,
  1285. "\nCREATE SPECTRA FROM TEXT DATA\n\n"
  1286. "USAGE: spectrum NAME outanalfile datafile pointcnt srate dur parameters\n"
  1287. "\n"
  1288. "where NAME can be any one of\n"
  1289. "\n"
  1290. "format fixed varying lines\n\n"
  1291. "Type 'spectrum format' for more info on spectrum format..ETC.\n");
  1292. return(USAGE_ONLY);
  1293. }
  1294. /**************************** CHECK_SPECTRUM_PARAM_VALIDITY_AND_CONSISTENCY *****************************/
  1295. int check_spectrum_param_validity_and_consistency(int **perm,dataptr dz)
  1296. {
  1297. int k, j, i, OK = 0;
  1298. double lastpkfrq;
  1299. if(dz->process == SPEKLINE && dz->mode > 0)
  1300. return FINISHED;
  1301. k = 1;
  1302. while(k < dz->iparam[SPEKPOINTS]) {
  1303. k *= 2;
  1304. if(k == dz->iparam[SPEKPOINTS]){
  1305. OK= 1;
  1306. break;
  1307. }
  1308. }
  1309. if(!OK) {
  1310. sprintf(errstr,"ANALYSIS POINTS PARAMETER MUST BE A POWER OF TWO.\n");
  1311. return(DATA_ERROR);
  1312. }
  1313. //RWD 2025
  1314. if(checkchans4format(k,dz->outfilename) == 0) {
  1315. sprintf(errstr,"Requested analysis channel count %d > 8192: too large for .ana format\n",k);
  1316. return DATA_ERROR;
  1317. }
  1318. if(dz->iparam[1] < 44100 || BAD_SR(dz->iparam[1])) {
  1319. sprintf(errstr,"INVALID SAMPLE RATE ENTERED (44100,48000,88200,96000 only).\n");
  1320. return(DATA_ERROR);
  1321. }
  1322. if(dz->process == SPEKLINE) {
  1323. dz->iparam[SPEKHARMS]++;
  1324. return FINISHED;
  1325. }
  1326. if(dz->process != SPEKFRMT) {
  1327. dz->iparam[SPEKHARMS]++; // Change count of harmonics to multiplier of max harmonic
  1328. if(dz->param[SPEKRANDF] > 1.0 && flteq(dz->param[SPEKRANDA],0.0)) {
  1329. sprintf(errstr,"NO MAX ATTENUATION EXCURSION SET FOR CHANNELS THAT VARY FROM AMPLITUDE ENVELOPE\n");
  1330. return(DATA_ERROR);
  1331. }
  1332. if(dz->param[SPEKRANDA] > 1.0 && flteq(dz->param[SPEKRANDF],0.0)) {
  1333. sprintf(errstr,"MAX AMPLITUDE EXCURSION SET, BUT PROPORTION OF CHANNELS TO FALL BELOW ENVELOPE, NOT SET.\n");
  1334. return(DATA_ERROR);
  1335. }
  1336. if((*perm = (int *)malloc(dz->iparam[SPEKPOINTS]*sizeof(int)))==NULL) {
  1337. sprintf(errstr,"NO MEMORY FOR CHANNEL PERMUTATIONS\n");
  1338. return(DATA_ERROR);
  1339. }
  1340. if(dz->brksize[SPEKWIDTH] > 0) {
  1341. lastpkfrq = 0.0;
  1342. for(j=0,k=1,i=1;j<dz->brksize[SPEKWIDTH] * 2; j+=2, k+=2, i++) {
  1343. //n= (int)round(dz->brk[SPEKWIDTH][j]);
  1344. if(dz->brk[SPEKWIDTH][j] <= lastpkfrq) {
  1345. sprintf(errstr,"SPECTRUM PEAK FRQ %d (%lf) IN WIDTH-ASPECT FILE IS INVALID OR NOT INCREASING\n",i,dz->brk[SPEKWIDTH][j]);
  1346. return(DATA_ERROR);
  1347. }
  1348. lastpkfrq = dz->brk[SPEKWIDTH][j];
  1349. if(dz->brk[SPEKWIDTH][k] > dz->param[SPEKMXASP]) {
  1350. sprintf(errstr,"SPECTRUM PEAK %d WIDTH-ASPECT (%lf) EXCEEDS TOP OF RANGE (%lf)\n",i,dz->brk[SPEKWIDTH][k],dz->param[SPEKMXASP]);
  1351. return(DATA_ERROR);
  1352. }
  1353. }
  1354. }
  1355. k = dz->vflag[1] + dz->vflag[2] + dz->vflag[3];
  1356. if(k > 1) {
  1357. sprintf(errstr,"w,s AND v FLAGS CANNOT BE USED IN COMBINATION WITH ONE ANOTHER.\n");
  1358. return(DATA_ERROR);
  1359. } else if(k > 0) {
  1360. if(!dz->brksize[SPEKWIDTH]) {
  1361. sprintf(errstr,"w,s AND v FLAGS CANNOT BE USED WITHOUT PEAK WIDTH DATA.\n");
  1362. return(DATA_ERROR);
  1363. }
  1364. }
  1365. }
  1366. return(FINISHED);
  1367. }
  1368. /********************************************************************************************/
  1369. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1370. {
  1371. if(!strcmp(prog_identifier_from_cmdline,"fixed")) dz->process = SPEKTRUM;
  1372. else if(!strcmp(prog_identifier_from_cmdline,"varying")) dz->process = SPEKVARY;
  1373. else if(!strcmp(prog_identifier_from_cmdline,"format")) dz->process = SPEKFRMT;
  1374. else if(!strcmp(prog_identifier_from_cmdline,"lines")) dz->process = SPEKLINE;
  1375. else {
  1376. sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  1377. // if(!sloom)
  1378. // fprintf(stderr,errstr);
  1379. return(USAGE_ONLY);
  1380. }
  1381. return(FINISHED);
  1382. }
  1383. /******************************** USAGE2 ********************************/
  1384. int usage2(char *str)
  1385. {
  1386. if(!strcmp(str,"format")) {
  1387. fprintf(stdout,
  1388. "USAGE: spectrum format outdatafile indatafile pointcnt srate\n"
  1389. "\n"
  1390. "Convert data in \"frq amp\" format to special format for sound conversion.\n"
  1391. "Assume data represents a graph of frq against amplitude.\n"
  1392. "SEE ALSO \"spectrum lines\"\n"
  1393. "\n"
  1394. "INDATAFILE text data as \"frq amp\" pairs.\n"
  1395. " frq range 0 - nyquist, with frequencies always increasing.\n"
  1396. " amp range, >= 0 .\n"
  1397. "OUTDATAFILE textfile as \"frq amp\" pairs\n"
  1398. " showing peaks, troughs and amplitude envelope.\n"
  1399. " Local peaks indicated by peak frq and amplitude.\n"
  1400. " Local troughs indicated by -(frq) and amplitude.\n"
  1401. " Elsewhere frq = zero (i.e. unspecific frq within channel)\n"
  1402. " amp = amplitude at channel centre frq.\n"
  1403. "POINTCNT Number of analysis points per window.\n"
  1404. "SRATE Samplerate of sound which will eventually be generated.\n"
  1405. "\n"
  1406. "Ideally, input should have many more frq points than pointcnt in output\n"
  1407. "if peaks and troughs of spectrum are to be accurately located.\n"
  1408. "\n");
  1409. } else if(!strcmp(str,"fixed")) {
  1410. fprintf(stdout,
  1411. "USAGE: spectrum fixed outanalfile datafile pointcnt srate dur\n"
  1412. " [-hH] [-bB] [-fF] [-rR] [-sS] [-aA] [-tT] [-wW] [-mM] [-d]\n"
  1413. "Generate fixed spectrum, from input data.\n"
  1414. "\n"
  1415. "DATAFILE textfile as \"frq amp\" pairs\n"
  1416. " showing peaks, troughs and amplitude envelope.\n"
  1417. " Local peaks indicated by peak frq and amplitude.\n"
  1418. " Local troughs indicated by -(frq) and amplitude.\n"
  1419. " Elsewhere frq = zero (i.e. unspecific frq within channel)\n"
  1420. " amp = amplitude at channel centre frq.\n"
  1421. "POINTCNT Number of analysis points per window.\n"
  1422. "SRATE Samplerate of sound which would be generated from anal output data.\n"
  1423. "DURATION Duration of sound output.\n"
  1424. "H Number of HARMONICS of peaks to be emphasized.\n"
  1425. "B BRIGHTNESS: relative loudness of successive harmonics.\n"
  1426. " (For TYPES 1,4 & 5 - see below - this is max brightness applied).\n"
  1427. "F FRACTION of analchans whose level falls below amp contour of spectrum.\n"
  1428. "R Max RANDOM attenuation excursion of amplitude in those channels.\n"
  1429. "S Freq SPREAD of peaks (0.0001 to 0.1)\n"
  1430. "A ATTENUATION applied to the spectrum.\n"
  1431. "T TYPE of spectrum:\n"
  1432. " 0 Brightness as specified.\n"
  1433. " 1 Brightness depend on peakwidth.\n"
  1434. " 2 Peak freq randonly varies (with time) across peak-width.\n"
  1435. " 3 Ditto, plus harmonics randvary independently of peak frq.\n"
  1436. " 4 Case 1 + Case 2\n"
  1437. " 5 Case 1 + Case 3\n"
  1438. "Following data only useful if t flag > 0\n"
  1439. "W WIDTH of peaks (as aspect ratio): zero means no peak info \n"
  1440. " otherwise expects a brkpoint file of pairs of\n"
  1441. " peak-frq and peak-aspect (pkheight/pkwidth/nyquist)\n"
  1442. "M MAXIMUM peakwidth aspect (corresponding to max brightness)\n"
  1443. "\n"
  1444. "-d Minimal dovetailing of output sound.\n"
  1445. "\n");
  1446. } else if(!strcmp(str,"varying")) {
  1447. fprintf(stdout,
  1448. "USAGE: spectrum variable outanalfile datafile pointcnt srate dur\n"
  1449. " [-hH] [-bB] [-fF] [-rR] [-aA] [-zZ] [-v]\n"
  1450. "Generate time-varying spectrum, from input data.\n"
  1451. "\n"
  1452. "DATAFILE Is a textfile with a series of spectra as text data\n"
  1453. " listed as \"frq amp\" pairs, showing peaks, troughs\n"
  1454. " and amplitude envelope.\n"
  1455. " Local peaks indicated by peak frq and amplitude.\n"
  1456. " Local troughs indicated by -(frq) and amplitude.\n"
  1457. " Elsewhere frq = zero (i.e. unspecific frq within channel)\n"
  1458. " amp = amplitude at channel centre frq.\n"
  1459. "POINTCNT Number of analysis points per window.\n"
  1460. "SRATE Samplerate of sound which would be generated from anal output data.\n"
  1461. "DURATION Duration of sound output.\n"
  1462. "H Number of HARMONICS of peaks to be emphasized.\n"
  1463. "B BRIGHTNESS: relative loudness of successive harmonics.\n"
  1464. "F FRACTION of analchans whose level falls below amp contour of spectrum.\n"
  1465. "R Max RANDOM attenuation excursion of amplitude in those channels..\n"
  1466. "A ATTENUATION applied to the spectrum.\n"
  1467. "Z Rate of ZOOM to new peak, if peak-chan changes.\n"
  1468. " 1 = linear: more than 1 zooms most rapidly near to peakwindow time:\n"
  1469. " less than 1 zooms least rapidly near to peakwindow time:\n"
  1470. "-v Minimal dovetailing of output sound.\n"
  1471. "\n");
  1472. } else if(!strcmp(str,"lines")) {
  1473. fprintf(stdout,
  1474. "USAGE: spectrum lines 1 outanalfile indatafile pointcnt srate duration \n"
  1475. " harmonics rolloff datafoot datatop specfoot spectop max datawarp ampwarp\n"
  1476. "USAGE: spectrum lines 2 outfiltfile indatafile duration \n"
  1477. " datafoot datatop specfoot spectop datawarp ampwarp\n"
  1478. "\n"
  1479. "Convert data in \"frq amp\" format representing spectral lines, to sound spectrum.\n"
  1480. "(Mode 2 produces a varifilt filter-file \"equivalent\" to the spectrum).\n"
  1481. "To convert a \"frq amp\" GRAPH to a spectrum ,see \"spectrum format\".\n"
  1482. "\n"
  1483. "INDATAFILE text data as \"frq amp\" pairs.\n"
  1484. " frequencies always increasing.\n"
  1485. " amp range, >= 0 .\n"
  1486. "OUTDATAFILE textfile as \"frq amp\" pairs\n"
  1487. " showing peaks, troughs and amplitude envelope.\n"
  1488. " Local peaks indicated by peak frq and amplitude.\n"
  1489. " Local troughs indicated by -(frq) and amplitude.\n"
  1490. " Elsewhere frq = zero (i.e. unspecific frq within channel)\n"
  1491. " amp = amplitude at channel centre frq.\n"
  1492. "POINTCNT Number of analysis points per window.\n"
  1493. "SRATE Samplerate of sound which will eventually be generated.\n"
  1494. "DURATION Duration of output spectrum.\n"
  1495. "HARMONICS Number of harmonics to add to original spectral components.\n"
  1496. "ROLLOFF Amplitude loss from one harmonic to next (dB).\n"
  1497. "DATAFOOT Lowest frq in INPUT to be represented in output.\n"
  1498. "DATATOP Highest frq in INPUT to be represented in output.\n"
  1499. "SPECFOOT Lowest frq in OUTPUT representation of spectrum.\n"
  1500. "SPECTOP Highest frq in OUTPUT representation of spectrum.\n"
  1501. "MAX Amplitude of maximum spectral channel.\n"
  1502. " (input data amplitudes first normalised to range 0 to 1.\n"
  1503. " these amplitudes are then scaled by \"max\"\n"
  1504. "DATAWARP If not equal to 1, input spectrum is mapped non-linearly...\n"
  1505. " if \"warp\" > 1, lower frqs are squeezed downwards.\n"
  1506. " if \"warp\" < 1, upper frqs are squeezed upwards.\n"
  1507. "AMPWARP If > 1, low input spectrum amplitudes are adjusted upwards.\n"
  1508. "\n");
  1509. } else
  1510. fprintf(stdout,"Unknown option '%s'\n",str);
  1511. return(USAGE_ONLY);
  1512. }
  1513. int usage3(char *str1,char *str2)
  1514. {
  1515. fprintf(stderr,"Insufficient parameters on command line.\n");
  1516. return(USAGE_ONLY);
  1517. }
  1518. /******************************** INIT_SPECSYNTH (redundant) ********************************/
  1519. void init_specsynth(dataptr dz)
  1520. {
  1521. dz->outfile->origrate = dz->infile->origrate = (int)dz->iparam[SPEKSRATE];
  1522. dz->outfile->stype = dz->infile->stype = SAMP_FLOAT;
  1523. dz->outfile->origstype = dz->infile->origstype = SAMP_SHORT;
  1524. dz->outfile->Mlen = dz->infile->Mlen = dz->iparam[SPEKPOINTS]; // 1024
  1525. dz->outfile->channels = dz->infile->channels = dz->outfile->Mlen + 2; // 1026
  1526. dz->wanted = dz->infile->channels;
  1527. dz->clength = dz->wanted/2;
  1528. dz->nyquist = (double)(dz->outfile->origrate / 2);
  1529. dz->outfile->Dfac = dz->infile->Dfac = dz->infile->Mlen / 8;
  1530. dz->outfile->arate = dz->infile->arate = (float) dz->outfile->origrate / (float)dz->outfile->Dfac;
  1531. dz->outfile->srate = dz->infile->srate = (int) dz->outfile->arate;
  1532. dz->frametime = (float)(1.0/dz->outfile->arate);
  1533. dz->wlength = (int)round(dz->param[SPEKDUR] * dz->outfile->arate);
  1534. dz->chwidth = dz->nyquist/(double)(dz->clength- 1);
  1535. dz->halfchwidth = dz->chwidth / 2;
  1536. dz->needpeaks = 0;
  1537. }
  1538. /**************************** ALLOCATE_SPECTRUM_BUFFER ******************************/
  1539. int allocate_spectrum_buffer(dataptr dz)
  1540. {
  1541. dz->buflen = dz->wanted;
  1542. if((dz->bigfbuf = (float*) malloc(dz->buflen * sizeof(float)))==NULL) {
  1543. sprintf(errstr,"INSUFFICIENT MEMORY for sound buffers.\n");
  1544. // if(!sloom)
  1545. // fprintf(stderr,errstr);
  1546. return(MEMORY_ERROR);
  1547. }
  1548. return(FINISHED);
  1549. }
  1550. /************************** HANDLE_THE_SPECIAL_DATA **********************************/
  1551. int handle_the_special_data(int *cmdlinecnt,char ***cmdline,dataptr dz)
  1552. {
  1553. int cnt/*, linecnt*/;
  1554. char *filename = (*cmdline)[0];
  1555. FILE *fp;
  1556. double *p, dummy;
  1557. char temp[200], *q;
  1558. if(filename[0]=='-' && filename[1]=='f') {
  1559. dz->floatsam_output = 1;
  1560. dz->true_outfile_stype = SAMP_FLOAT;
  1561. filename+= 2;
  1562. }
  1563. if((fp = fopen(filename,"r"))==NULL) {
  1564. sprintf(errstr, "Can't open data file %s to read data.\n",filename);
  1565. // if(!sloom)
  1566. // fprintf(stderr,errstr);
  1567. return(DATA_ERROR);
  1568. }
  1569. cnt = 0;
  1570. p = &dummy;
  1571. while(fgets(temp,200,fp)==temp) {
  1572. q = temp;
  1573. if(*q == ';') // Allow comments in file
  1574. continue;
  1575. while(get_float_with_e_from_within_string(&q,p))
  1576. cnt++;
  1577. }
  1578. if(cnt == 0) {
  1579. sprintf(errstr,"No data in data file %s\n",filename);
  1580. // if(!sloom)
  1581. // fprintf(stderr,errstr);
  1582. return(DATA_ERROR);
  1583. }
  1584. if((dz->parray = (double **)malloc(sizeof(double *)))==NULL) {
  1585. sprintf(errstr,"INSUFFICIENT MEMORY for input data in file %s.\n",filename);
  1586. // if(!sloom)
  1587. // fprintf(stderr,errstr);
  1588. return(MEMORY_ERROR);
  1589. }
  1590. cnt += 4; // Allow space for zero and nyquist values, if need to be added later
  1591. if((dz->parray[0] = (double *)malloc(cnt * sizeof(double)))==NULL) {
  1592. sprintf(errstr,"INSUFFICIENT MEMORY for input data in file %s.\n",filename);
  1593. // if(!sloom)
  1594. // fprintf(stderr,errstr);
  1595. return(MEMORY_ERROR);
  1596. }
  1597. cnt -= 4;
  1598. fseek(fp,0,0);
  1599. // linecnt = 1;
  1600. p = dz->parray[0];
  1601. while(fgets(temp,200,fp)==temp) {
  1602. q = temp;
  1603. if(*q == ';') // Allow comments in file
  1604. continue;
  1605. while(get_float_with_e_from_within_string(&q,p)) {
  1606. p++;
  1607. }
  1608. // linecnt++;
  1609. }
  1610. if(fclose(fp)<0) {
  1611. fprintf(stdout,"WARNING: Failed to close file %s.\n",filename);
  1612. fflush(stdout);
  1613. }
  1614. dz->itemcnt = cnt;
  1615. (*cmdline)++;
  1616. (*cmdlinecnt)--;
  1617. return(FINISHED);
  1618. }
  1619. /************************** TEST_THE_SPECIAL_DATA **********************************/
  1620. int test_the_special_data(dataptr dz)
  1621. {
  1622. double *p, maxamp = 0.0, normaliser = 1.0, lastfrq = -1.0;
  1623. int isamp = 0, linecnt = 1, lastfrqindx = dz->itemcnt - 2;
  1624. int n,m;
  1625. p = dz->parray[0];
  1626. while(linecnt <= dz->itemcnt/2) {
  1627. if(isamp) {
  1628. if(*p < 0.0) {
  1629. sprintf(errstr,"Amp (%lf) out of range ( < 0 ) at line %d in datafile.\n",*p,linecnt);
  1630. return(DATA_ERROR);
  1631. }
  1632. maxamp = max(*p,maxamp);
  1633. } else {
  1634. if(dz->process == SPEKLINE) { /* TW: Can accept frq vals above output-nyquist */
  1635. if(*p < 0.0) {
  1636. sprintf(errstr,"Frq (%lf) out of range (< 0 ) at line %d in datafile.\n",*p,linecnt);
  1637. return(DATA_ERROR);
  1638. }
  1639. if(*p < lastfrq) {
  1640. sprintf(errstr,"Frqs (%lf) do not increase at line %d in datafile.\n",*p,linecnt);
  1641. return(DATA_ERROR);
  1642. }
  1643. lastfrq = *p;
  1644. } else if(dz->process == SPEKFRMT) {
  1645. if(*p < 0.0 || *p > dz->nyquist) {
  1646. sprintf(errstr,"Frq (%lf) out of range (0 - %lf) at line %d in datafile.\n",*p,dz->nyquist,linecnt);
  1647. return(DATA_ERROR);
  1648. }
  1649. if(*p < lastfrq) {
  1650. sprintf(errstr,"Frqs (%lf) do not increase at line %d in datafile.\n",*p,linecnt);
  1651. return(DATA_ERROR);
  1652. }
  1653. lastfrq = *p;
  1654. } else if(fabs(*p) > dz->nyquist) {
  1655. sprintf(errstr,"Frq (%lf) out of range (0 - %lf) at line %d in datafile.\n",fabs(*p),dz->nyquist,linecnt);
  1656. return(DATA_ERROR);
  1657. }
  1658. }
  1659. if(isamp)
  1660. linecnt++;
  1661. isamp = !isamp;
  1662. p++;
  1663. }
  1664. if(maxamp > 1.0) {
  1665. normaliser = 1.0/maxamp;
  1666. p = dz->parray[0];
  1667. p++;
  1668. linecnt = 1;
  1669. while(linecnt <= dz->itemcnt/2) {
  1670. *p *= normaliser;
  1671. linecnt++;
  1672. p += 2;
  1673. }
  1674. }
  1675. switch(dz->process) {
  1676. case(SPEKFRMT):
  1677. if(!flteq(dz->parray[0][lastfrqindx],dz->nyquist)) { // Space has been allocated for these extra points
  1678. dz->parray[0][dz->itemcnt] = dz->nyquist;
  1679. dz->itemcnt++;
  1680. dz->parray[0][dz->itemcnt] = 0.0;
  1681. dz->itemcnt++;
  1682. }
  1683. if(dz->parray[0][0] != 0.0) {
  1684. dz->itemcnt += 2;
  1685. n = dz->itemcnt - 1;
  1686. m = n - 2;
  1687. while(m >= 0) {
  1688. dz->parray[0][n] = dz->parray[0][m];
  1689. m--;
  1690. n--;
  1691. }
  1692. dz->parray[0][0] = 0.0;
  1693. dz->parray[0][1] = 0.0;
  1694. }
  1695. break;
  1696. case(SPEKTRUM):
  1697. if(dz->itemcnt != dz->wanted) {
  1698. sprintf(errstr,"Data count (%d) should be just 2 more than analysis-points parameter (%d)\n",dz->itemcnt,dz->wanted - 2);
  1699. return(DATA_ERROR);
  1700. }
  1701. break;
  1702. case(SPEKVARY):
  1703. if((dz->itemcnt / dz->wanted) * dz->wanted != dz->itemcnt) {
  1704. sprintf(errstr,"Data count (%d) in file must be a multiple of (analysis_points_parameter + 2) (%d)\n",dz->itemcnt,dz->wanted);
  1705. return(DATA_ERROR);
  1706. }
  1707. dz->itemcnt /= dz->wanted;
  1708. break;
  1709. }
  1710. return(FINISHED);
  1711. }
  1712. /************************** SPECTRUM **********************************/
  1713. int spectrum(int *perm,dataptr dz)
  1714. {
  1715. int vc, cc, exit_status;
  1716. double thistime, dfade, frq, chbot, harmamp, spreaddnratio = 0.0, spreadupratio = 0.0, fader;
  1717. double orig_brightness, pkaspect, pkwidth, pkfrq, pkoffset;
  1718. float orig_frequency;
  1719. int *peaked, peakcnt/*, orig_peakcnt*/;
  1720. /* ESTABLISH BRKPOINT TABLE OF TRUE AMPLITUDE ENVELOPE OF INPUT DATA */
  1721. if((dz->brk[0] = (double *)malloc(dz->clength * 2 * sizeof(double)))==NULL) {
  1722. sprintf(errstr,"Establishing brktable for amp envelope failed.\n");
  1723. // if(!sloom)
  1724. // fprintf(stderr,errstr);
  1725. return(MEMORY_ERROR);
  1726. }
  1727. if((peaked = (int *)malloc(dz->clength * sizeof(int)))==NULL) {
  1728. sprintf(errstr,"Establishing brktable for peak markers.\n");
  1729. // if(!sloom)
  1730. // fprintf(stderr,errstr);
  1731. return(MEMORY_ERROR);
  1732. }
  1733. if(dz->param[SPEKSPRED] > 0) {
  1734. spreaddnratio = 1 - dz->param[SPEKSPRED];
  1735. spreadupratio = 1 + dz->param[SPEKSPRED];
  1736. }
  1737. dz->brksize[0] = dz->clength;
  1738. dz->brkinit[0] = 0;
  1739. frq = 0.0;
  1740. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc +=2) {
  1741. dz->brk[0][vc+1] = dz->parray[0][vc+1];
  1742. if(flteq(dz->parray[0][vc],0.0)) // If input chan frq is unassigned (0.0) set frq to midfrq of chan
  1743. dz->brk[0][vc] = frq;
  1744. else // Else, set frq to absolute val of input frq (maxima are +frq, minima are -frq)
  1745. dz->brk[0][vc] = fabs(dz->parray[0][vc]);
  1746. frq += dz->chwidth;
  1747. }
  1748. /* ZERO START WINDOW */
  1749. thistime = 0.0;
  1750. frq = 0;
  1751. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc +=2) {
  1752. dz->bigfbuf[AMPP] = 0.0f;
  1753. dz->bigfbuf[FREQ] = (float)frq;
  1754. frq += dz->chwidth;
  1755. }
  1756. if((exit_status = write_samps(dz->bigfbuf,dz->wanted,dz))<0)
  1757. return(exit_status);
  1758. thistime += dz->frametime;
  1759. /* 88 WINDOW FADE-IN */
  1760. if(!dz->is_rectified) {
  1761. dfade = 4096;
  1762. while(dfade > 1) {
  1763. chbot = -dz->chwidth;
  1764. for(cc = 0; cc < dz->clength; cc++)
  1765. peaked[cc] = 0;
  1766. peakcnt = 0;
  1767. // orig_peakcnt = 0;
  1768. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc +=2) {
  1769. if(peaked[cc]) {
  1770. if(cc > 0) { // IF already a marked peak (i.e. a harmonic of a previous peak)
  1771. if(dz->parray[0][vc] > 0.0) { // BUT this channel is a peak in orig data ... overwrite harmonic with new peak info
  1772. dz->bigfbuf[AMPP] = (float)(dz->param[SPEKGAIN] * dz->parray[0][vc+1]/(double)dfade);
  1773. dz->bigfbuf[FREQ] = (float)dz->parray[0][vc];
  1774. pkwidth = 0.0;
  1775. switch(dz->iparam[SPEKTYPE]) {
  1776. case(0): // Brightness defined by brightness-rolloff param
  1777. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  1778. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  1779. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  1780. }
  1781. break;
  1782. case(1): // Brightness (also) determined by peak-width-aspect
  1783. orig_brightness = dz->param[SPEKBRITE];
  1784. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  1785. pkaspect = dz->param[SPEKWIDTH];
  1786. dz->param[SPEKBRITE] = (pkaspect/dz->param[SPEKMXASP]) * orig_brightness;
  1787. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  1788. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  1789. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  1790. }
  1791. dz->param[SPEKBRITE] = orig_brightness;
  1792. break;
  1793. case(2): // Brightness as case 0 : frq of peaks random spread across peak-width
  1794. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  1795. pkaspect = dz->param[SPEKWIDTH];
  1796. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  1797. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  1798. pkoffset = drand48() * pkwidth;
  1799. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  1800. pkfrq += pkoffset;
  1801. dz->bigfbuf[FREQ] = (float)pkfrq;
  1802. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  1803. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  1804. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  1805. }
  1806. break;
  1807. case(3): // As case 2 : frq of harmonics also random spread across peak-width
  1808. orig_frequency = dz->bigfbuf[FREQ];
  1809. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  1810. pkaspect = dz->param[SPEKWIDTH];
  1811. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  1812. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  1813. pkoffset = drand48() * pkwidth;
  1814. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  1815. pkfrq += pkoffset;
  1816. dz->bigfbuf[FREQ] = (float)pkfrq;
  1817. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  1818. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  1819. insert_harmonics(&peaked,&peakcnt,harmamp,orig_frequency,pkwidth,dz);
  1820. }
  1821. break;
  1822. case(4): // case 1 + case 2
  1823. orig_brightness = dz->param[SPEKBRITE];
  1824. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  1825. pkaspect = dz->param[SPEKWIDTH];
  1826. dz->param[SPEKBRITE] = (pkaspect/dz->param[SPEKMXASP]) * orig_brightness;
  1827. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  1828. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  1829. pkoffset = drand48() * pkwidth;
  1830. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  1831. pkfrq += pkoffset;
  1832. dz->bigfbuf[FREQ] = (float)pkfrq;
  1833. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  1834. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  1835. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  1836. }
  1837. dz->param[SPEKBRITE] = orig_brightness;
  1838. break;
  1839. case(5): // case 1 + case 3
  1840. orig_brightness = dz->param[SPEKBRITE];
  1841. orig_frequency = dz->bigfbuf[FREQ];
  1842. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  1843. pkaspect = dz->param[SPEKWIDTH];
  1844. dz->param[SPEKBRITE] = (pkaspect/dz->param[SPEKMXASP]) * orig_brightness;
  1845. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  1846. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  1847. pkoffset = drand48() * pkwidth;
  1848. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  1849. pkfrq += pkoffset;
  1850. dz->bigfbuf[FREQ] = (float)pkfrq;
  1851. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  1852. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  1853. insert_harmonics(&peaked,&peakcnt,harmamp,orig_frequency,pkwidth,dz);
  1854. }
  1855. dz->param[SPEKBRITE] = orig_brightness;
  1856. break;
  1857. }
  1858. }
  1859. }
  1860. } else if(dz->parray[0][vc] <= 0.0) { // Frq unspecific (marked as 0.0), assign rand frq within chan
  1861. frq = drand48() * dz->chwidth;
  1862. frq += chbot;
  1863. frq = max(frq,0.0);
  1864. frq = min(frq,dz->nyquist);
  1865. dz->bigfbuf[FREQ] = (float)frq;
  1866. if((exit_status = read_value_from_brktable(frq,0,dz))<0) // Read amplitude from frq/amp brktable
  1867. return(exit_status);
  1868. dz->bigfbuf[AMPP] = (float)(dz->param[SPEKGAIN] * dz->param[0]/(double)dfade); // NB dz->param[0] being used to store brkpnt read val
  1869. } else { // Frq is a peak, retain it and its amplitude
  1870. dz->bigfbuf[AMPP] = (float)(dz->param[SPEKGAIN] * dz->parray[0][vc+1]/(double)dfade);
  1871. dz->bigfbuf[FREQ] = (float)dz->parray[0][vc];
  1872. peaked[cc] = 1;
  1873. pkwidth = 0.0;
  1874. // orig_peakcnt++;
  1875. peakcnt++;
  1876. switch(dz->iparam[SPEKTYPE]) {
  1877. case(0): // Brightness defined by brightness-rolloff param
  1878. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  1879. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  1880. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  1881. }
  1882. break;
  1883. case(1): // Brightness (also) determined by peak-width-aspect
  1884. orig_brightness = dz->param[SPEKBRITE];
  1885. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  1886. pkaspect = dz->param[SPEKWIDTH];
  1887. dz->param[SPEKBRITE] = (pkaspect/dz->param[SPEKMXASP]) * orig_brightness;
  1888. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  1889. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  1890. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  1891. }
  1892. dz->param[SPEKBRITE] = orig_brightness;
  1893. break;
  1894. case(2): // Brightness as case 0 : frq of peaks random spread across peak-width
  1895. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  1896. pkaspect = dz->param[SPEKWIDTH];
  1897. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  1898. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  1899. pkoffset = drand48() * pkwidth;
  1900. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  1901. pkfrq += pkoffset;
  1902. dz->bigfbuf[FREQ] = (float)pkfrq;
  1903. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  1904. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  1905. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  1906. }
  1907. break;
  1908. case(3): // As case 2 : frq of harmonics also random spread across peak-width
  1909. orig_frequency = dz->bigfbuf[FREQ];
  1910. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  1911. pkaspect = dz->param[SPEKWIDTH];
  1912. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  1913. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  1914. pkoffset = drand48() * pkwidth;
  1915. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  1916. pkfrq += pkoffset;
  1917. dz->bigfbuf[FREQ] = (float)pkfrq;
  1918. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  1919. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  1920. insert_harmonics(&peaked,&peakcnt,harmamp,orig_frequency,pkwidth,dz);
  1921. }
  1922. break;
  1923. case(4): // case 1 + case 2
  1924. orig_brightness = dz->param[SPEKBRITE];
  1925. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  1926. pkaspect = dz->param[SPEKWIDTH];
  1927. dz->param[SPEKBRITE] = (pkaspect/dz->param[SPEKMXASP]) * orig_brightness;
  1928. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  1929. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  1930. pkoffset = drand48() * pkwidth;
  1931. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  1932. pkfrq += pkoffset;
  1933. dz->bigfbuf[FREQ] = (float)pkfrq;
  1934. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  1935. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  1936. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  1937. }
  1938. dz->param[SPEKBRITE] = orig_brightness;
  1939. break;
  1940. case(5): // case 1 + case 3
  1941. orig_brightness = dz->param[SPEKBRITE];
  1942. orig_frequency = dz->bigfbuf[FREQ];
  1943. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  1944. pkaspect = dz->param[SPEKWIDTH];
  1945. dz->param[SPEKBRITE] = (pkaspect/dz->param[SPEKMXASP]) * orig_brightness;
  1946. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  1947. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  1948. pkoffset = drand48() * pkwidth;
  1949. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  1950. pkfrq += pkoffset;
  1951. dz->bigfbuf[FREQ] = (float)pkfrq;
  1952. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  1953. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  1954. insert_harmonics(&peaked,&peakcnt,harmamp,orig_frequency,pkwidth,dz);
  1955. }
  1956. dz->param[SPEKBRITE] = orig_brightness;
  1957. break;
  1958. }
  1959. }
  1960. chbot += dz->chwidth;
  1961. }
  1962. if(dz->param[SPEKRANDF] > 0.0)
  1963. randomiseamps(perm,peaked,dz);
  1964. if(dz->param[SPEKSPRED] > 0)
  1965. spread_peaks(peaked,spreaddnratio,spreadupratio,dz);
  1966. if((exit_status = write_samps(dz->bigfbuf,dz->wanted,dz))<0)
  1967. return(exit_status);
  1968. dfade /= 1.1;
  1969. thistime += dz->frametime;
  1970. }
  1971. }
  1972. while(thistime < dz->param[SPEKDUR]) {
  1973. chbot = -dz->chwidth;
  1974. for(cc = 0; cc < dz->clength; cc++)
  1975. peaked[cc] = 0;
  1976. peakcnt = 0;
  1977. // orig_peakcnt = 0;
  1978. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc +=2) {
  1979. if(peaked[cc]) {
  1980. if(cc > 0) { // IF already a marked peak (i.e. a harmonic of a previous peak)
  1981. if(dz->parray[0][vc] > 0.0) { // BUT this channel is a peak in orig data ... overwrite harmonic with new peak info
  1982. dz->bigfbuf[AMPP] = (float)(dz->param[SPEKGAIN] * dz->parray[0][vc+1]);
  1983. dz->bigfbuf[FREQ] = (float)dz->parray[0][vc];
  1984. pkwidth = 0.0;
  1985. //aspindx = (orig_peakcnt * 2) + 1;
  1986. switch(dz->iparam[SPEKTYPE]) {
  1987. case(0): // Brightness defined by brightness-rolloff param
  1988. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  1989. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  1990. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  1991. }
  1992. break;
  1993. case(1): // Brightness (also) determined by peak-width-aspect
  1994. orig_brightness = dz->param[SPEKBRITE];
  1995. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  1996. pkaspect = dz->param[SPEKWIDTH];
  1997. dz->param[SPEKBRITE] = (pkaspect/dz->param[SPEKMXASP]) * orig_brightness;
  1998. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  1999. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2000. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  2001. }
  2002. dz->param[SPEKBRITE] = orig_brightness;
  2003. break;
  2004. case(2): // Brightness as case 0 : frq of peaks random spread across peak-width
  2005. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  2006. pkaspect = dz->param[SPEKWIDTH];
  2007. pkwidth = ((dz->parray[0][vc+1])/pkaspect) * dz->nyquist;
  2008. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  2009. pkoffset = drand48() * pkwidth;
  2010. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  2011. pkfrq += pkoffset;
  2012. dz->bigfbuf[FREQ] = (float)pkfrq;
  2013. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2014. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2015. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  2016. }
  2017. break;
  2018. case(3): // As case 2 : frq of harmonics also random spread across peak-width
  2019. orig_frequency = dz->bigfbuf[FREQ];
  2020. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  2021. pkaspect = dz->param[SPEKWIDTH];
  2022. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  2023. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  2024. pkoffset = drand48() * pkwidth;
  2025. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  2026. pkfrq += pkoffset;
  2027. dz->bigfbuf[FREQ] = (float)pkfrq;
  2028. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2029. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2030. insert_harmonics(&peaked,&peakcnt,harmamp,orig_frequency,pkwidth,dz);
  2031. }
  2032. break;
  2033. case(4): // case 1 + case 2
  2034. orig_brightness = dz->param[SPEKBRITE];
  2035. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  2036. pkaspect = dz->param[SPEKWIDTH];
  2037. dz->param[SPEKBRITE] = (pkaspect/dz->param[SPEKMXASP]) * orig_brightness;
  2038. pkwidth = ((dz->parray[0][vc+1])/pkaspect) * dz->nyquist;
  2039. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  2040. pkoffset = drand48() * pkwidth;
  2041. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  2042. pkfrq += pkoffset;
  2043. dz->bigfbuf[FREQ] = (float)pkfrq;
  2044. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2045. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2046. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  2047. }
  2048. dz->param[SPEKBRITE] = orig_brightness;
  2049. break;
  2050. case(5): // case 1 + case 3
  2051. orig_brightness = dz->param[SPEKBRITE];
  2052. orig_frequency = dz->bigfbuf[FREQ];
  2053. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  2054. pkaspect = dz->param[SPEKWIDTH];
  2055. dz->param[SPEKBRITE] = (pkaspect/dz->param[SPEKMXASP]) * orig_brightness;
  2056. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  2057. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  2058. pkoffset = drand48() * pkwidth;
  2059. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  2060. pkfrq += pkoffset;
  2061. dz->bigfbuf[FREQ] = (float)pkfrq;
  2062. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2063. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2064. insert_harmonics(&peaked,&peakcnt,harmamp,orig_frequency,pkwidth,dz);
  2065. }
  2066. dz->param[SPEKBRITE] = orig_brightness;
  2067. break;
  2068. }
  2069. }
  2070. }
  2071. } else if(dz->parray[0][vc] <= 0.0) {
  2072. frq = drand48() * dz->chwidth; // Frq unspecific, assign rand frq within chan
  2073. frq += chbot;
  2074. frq = max(frq,0.0);
  2075. frq = min(frq,dz->nyquist);
  2076. dz->bigfbuf[FREQ] = (float)frq;
  2077. if((exit_status = read_value_from_brktable(frq,0,dz))<0) // Read amplitude from frq/amp brktable
  2078. return(exit_status);
  2079. dz->bigfbuf[AMPP] = (float)(dz->param[SPEKGAIN] * dz->param[0]);
  2080. } else {
  2081. dz->bigfbuf[AMPP] = (float)(dz->param[SPEKGAIN] * dz->parray[0][vc+1]); // Peaks take on their true values
  2082. dz->bigfbuf[FREQ] = (float)fabs(dz->parray[0][vc]); // BUT NB input data is frq/amp ... output data is amp/frq
  2083. peaked[cc] = 1;
  2084. pkwidth = 0.0;
  2085. //aspindx = (orig_peakcnt * 2) + 1;
  2086. // orig_peakcnt++;
  2087. peakcnt++;
  2088. switch(dz->iparam[SPEKTYPE]) {
  2089. case(0): // Brightness defined by brightness-rolloff param
  2090. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2091. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2092. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  2093. }
  2094. break;
  2095. case(1): // Brightness (also) determined by peak-width-aspect
  2096. orig_brightness = dz->param[SPEKBRITE];
  2097. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  2098. pkaspect = dz->param[SPEKWIDTH];
  2099. dz->param[SPEKBRITE] = (pkaspect/dz->param[SPEKMXASP]) * orig_brightness;
  2100. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2101. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2102. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  2103. }
  2104. dz->param[SPEKBRITE] = orig_brightness;
  2105. break;
  2106. case(2): // Brightness as case 0 : frq of peaks random spread across peak-width
  2107. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  2108. pkaspect = dz->param[SPEKWIDTH];
  2109. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  2110. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  2111. pkoffset = drand48() * pkwidth;
  2112. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  2113. pkfrq += pkoffset;
  2114. dz->bigfbuf[FREQ] = (float)pkfrq;
  2115. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2116. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2117. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  2118. }
  2119. break;
  2120. case(3): // As case 2 : frq of harmonics also random spread across peak-width
  2121. orig_frequency = dz->bigfbuf[FREQ];
  2122. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  2123. pkaspect = dz->param[SPEKWIDTH];
  2124. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  2125. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  2126. pkoffset = drand48() * pkwidth;
  2127. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  2128. pkfrq += pkoffset;
  2129. dz->bigfbuf[FREQ] = (float)pkfrq;
  2130. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2131. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2132. insert_harmonics(&peaked,&peakcnt,harmamp,orig_frequency,pkwidth,dz);
  2133. }
  2134. break;
  2135. case(4): // case 1 + case 2
  2136. orig_brightness = dz->param[SPEKBRITE];
  2137. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  2138. pkaspect = dz->param[SPEKWIDTH];
  2139. dz->param[SPEKBRITE] = (pkaspect/dz->param[SPEKMXASP]) * orig_brightness;
  2140. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  2141. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  2142. pkoffset = drand48() * pkwidth;
  2143. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  2144. pkfrq += pkoffset;
  2145. dz->bigfbuf[FREQ] = (float)pkfrq;
  2146. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2147. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2148. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  2149. }
  2150. dz->param[SPEKBRITE] = orig_brightness;
  2151. break;
  2152. case(5): // case 1 + case 3
  2153. orig_brightness = dz->param[SPEKBRITE];
  2154. orig_frequency = dz->bigfbuf[FREQ];
  2155. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  2156. pkaspect = dz->param[SPEKWIDTH];
  2157. dz->param[SPEKBRITE] = (pkaspect/dz->param[SPEKMXASP]) * orig_brightness;
  2158. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  2159. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  2160. pkoffset = drand48() * pkwidth;
  2161. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  2162. pkfrq += pkoffset;
  2163. dz->bigfbuf[FREQ] = (float)pkfrq;
  2164. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2165. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2166. insert_harmonics(&peaked,&peakcnt,harmamp,orig_frequency,pkwidth,dz);
  2167. }
  2168. dz->param[SPEKBRITE] = orig_brightness;
  2169. break;
  2170. }
  2171. }
  2172. chbot += dz->chwidth;
  2173. }
  2174. if(dz->param[SPEKRANDF] > 0.0)
  2175. randomiseamps(perm,peaked,dz);
  2176. if(dz->param[SPEKSPRED] > 0)
  2177. spread_peaks(peaked,spreaddnratio,spreadupratio,dz);
  2178. if((exit_status = write_samps(dz->bigfbuf,dz->wanted,dz))<0) {
  2179. return(exit_status);
  2180. }
  2181. thistime += dz->frametime;
  2182. }
  2183. dfade = 1.1;
  2184. if(dz->is_rectified) {
  2185. dfade = 1.0;
  2186. fader = 4.0;
  2187. } else {
  2188. /* 87 WINDOW FADE-OUT */
  2189. dfade = 1.1;
  2190. fader = 1.1;
  2191. }
  2192. while(dfade <= 4096) {
  2193. chbot = -dz->chwidth;
  2194. for(cc = 0; cc < dz->clength; cc++)
  2195. peaked[cc] = 0;
  2196. peakcnt = 0;
  2197. // orig_peakcnt = 0;
  2198. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc +=2) {
  2199. if(peaked[cc]) {
  2200. if(cc > 0) { // IF already a marked peak (i.e. a harmonic of a previous peak)
  2201. if(dz->parray[0][vc] > 0.0) { // BUT this channel is a peak in orig data ... overwrite harmonic with new peak info
  2202. dz->bigfbuf[AMPP] = (float)(dz->param[SPEKGAIN] * dz->parray[0][vc+1]/dfade);
  2203. dz->bigfbuf[FREQ] = (float)dz->parray[0][vc];
  2204. pkwidth = 0.0;
  2205. //aspindx = (orig_peakcnt * 2) + 1;
  2206. switch(dz->iparam[SPEKTYPE]) {
  2207. case(0): // Brightness defined by brightness-rolloff param
  2208. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2209. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2210. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  2211. }
  2212. break;
  2213. case(1): // Brightness (also) determined by peak-width-aspect
  2214. orig_brightness = dz->param[SPEKBRITE];
  2215. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  2216. pkaspect = dz->param[SPEKWIDTH];
  2217. dz->param[SPEKBRITE] = (pkaspect/dz->param[SPEKMXASP]) * orig_brightness;
  2218. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2219. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2220. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  2221. }
  2222. dz->param[SPEKBRITE] = orig_brightness;
  2223. break;
  2224. case(2): // Brightness as case 0 : frq of peaks random spread across peak-width
  2225. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  2226. pkaspect = dz->param[SPEKWIDTH];
  2227. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  2228. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  2229. pkoffset = drand48() * pkwidth;
  2230. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  2231. pkfrq += pkoffset;
  2232. dz->bigfbuf[FREQ] = (float)pkfrq;
  2233. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2234. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2235. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  2236. }
  2237. break;
  2238. case(3): // As case 2 : frq of harmonics also random spread across peak-width
  2239. orig_frequency = dz->bigfbuf[FREQ];
  2240. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  2241. pkaspect = dz->param[SPEKWIDTH];
  2242. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  2243. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  2244. pkoffset = drand48() * pkwidth;
  2245. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  2246. pkfrq += pkoffset;
  2247. dz->bigfbuf[FREQ] = (float)pkfrq;
  2248. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2249. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2250. insert_harmonics(&peaked,&peakcnt,harmamp,orig_frequency,pkwidth,dz);
  2251. }
  2252. break;
  2253. case(4): // case 1 + case 2
  2254. orig_brightness = dz->param[SPEKBRITE];
  2255. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  2256. pkaspect = dz->param[SPEKWIDTH];
  2257. dz->param[SPEKBRITE] = (pkaspect/dz->param[SPEKMXASP]) * orig_brightness;
  2258. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  2259. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  2260. pkoffset = drand48() * pkwidth;
  2261. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  2262. pkfrq += pkoffset;
  2263. dz->bigfbuf[FREQ] = (float)pkfrq;
  2264. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2265. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2266. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  2267. }
  2268. dz->param[SPEKBRITE] = orig_brightness;
  2269. break;
  2270. case(5): // case 1 + case 3
  2271. orig_brightness = dz->param[SPEKBRITE];
  2272. orig_frequency = dz->bigfbuf[FREQ];
  2273. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  2274. pkaspect = dz->param[SPEKWIDTH];
  2275. dz->param[SPEKBRITE] = (pkaspect/dz->param[SPEKMXASP]) * orig_brightness;
  2276. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  2277. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  2278. pkoffset = drand48() * pkwidth;
  2279. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  2280. pkfrq += pkoffset;
  2281. dz->bigfbuf[FREQ] = (float)pkfrq;
  2282. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2283. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2284. insert_harmonics(&peaked,&peakcnt,harmamp,orig_frequency,pkwidth,dz);
  2285. }
  2286. dz->param[SPEKBRITE] = orig_brightness;
  2287. break;
  2288. }
  2289. }
  2290. }
  2291. } else if(dz->parray[0][vc] <= 0.0) {
  2292. frq = drand48() * dz->chwidth; // Frq unspecific, assign rand frq within chan
  2293. frq += chbot;
  2294. frq = max(frq,0.0);
  2295. frq = min(frq,dz->nyquist);
  2296. dz->bigfbuf[FREQ] = (float)frq;
  2297. if((exit_status = read_value_from_brktable(frq,0,dz))<0) // Read amplitude from frq/amp brktable
  2298. return(exit_status);
  2299. dz->bigfbuf[AMPP] = (float)(dz->param[SPEKGAIN] * dz->param[0]/(double)dfade);
  2300. } else {
  2301. dz->bigfbuf[AMPP] = (float)(dz->param[SPEKGAIN] * dz->parray[0][vc+1]/(double)dfade);
  2302. dz->bigfbuf[FREQ] = (float)dz->parray[0][vc];
  2303. peaked[cc] = 1;
  2304. pkwidth = 0.0;
  2305. //aspindx = (orig_peakcnt * 2) + 1;
  2306. // orig_peakcnt++;
  2307. peakcnt++;
  2308. switch(dz->iparam[SPEKTYPE]) {
  2309. case(0): // Brightness defined by brightness-rolloff param
  2310. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2311. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2312. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  2313. }
  2314. break;
  2315. case(1): // Brightness (also) determined by peak-width-aspect
  2316. orig_brightness = dz->param[SPEKBRITE];
  2317. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  2318. pkaspect = dz->param[SPEKWIDTH];
  2319. dz->param[SPEKBRITE] = (pkaspect/dz->param[SPEKMXASP]) * orig_brightness;
  2320. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2321. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2322. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  2323. }
  2324. dz->param[SPEKBRITE] = orig_brightness;
  2325. break;
  2326. case(2): // Brightness as case 0 : frq of peaks random spread across peak-width
  2327. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  2328. pkaspect = dz->param[SPEKWIDTH];
  2329. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  2330. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  2331. pkoffset = drand48() * pkwidth;
  2332. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  2333. pkfrq += pkoffset;
  2334. dz->bigfbuf[FREQ] = (float)pkfrq;
  2335. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2336. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2337. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  2338. }
  2339. break;
  2340. case(3): // As case 2 : frq of harmonics also random spread across peak-width
  2341. orig_frequency = dz->bigfbuf[FREQ];
  2342. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  2343. pkaspect = dz->param[SPEKWIDTH];
  2344. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  2345. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  2346. pkoffset = drand48() * pkwidth;
  2347. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  2348. pkfrq += pkoffset;
  2349. dz->bigfbuf[FREQ] = (float)pkfrq;
  2350. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2351. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2352. insert_harmonics(&peaked,&peakcnt,harmamp,orig_frequency,pkwidth,dz);
  2353. }
  2354. break;
  2355. case(4): // case 1 + case 2
  2356. orig_brightness = dz->param[SPEKBRITE];
  2357. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  2358. pkaspect = dz->param[SPEKWIDTH];
  2359. dz->param[SPEKBRITE] = (pkaspect/dz->param[SPEKMXASP]) * orig_brightness;
  2360. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  2361. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  2362. pkoffset = drand48() * pkwidth;
  2363. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  2364. pkfrq += pkoffset;
  2365. dz->bigfbuf[FREQ] = (float)pkfrq;
  2366. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2367. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2368. insert_harmonics(&peaked,&peakcnt,harmamp,dz->bigfbuf[FREQ],pkwidth,dz);
  2369. }
  2370. dz->param[SPEKBRITE] = orig_brightness;
  2371. break;
  2372. case(5): // case 1 + case 3
  2373. orig_brightness = dz->param[SPEKBRITE];
  2374. orig_frequency = dz->bigfbuf[FREQ];
  2375. read_nearest_value_from_brktable(dz->bigfbuf[FREQ],SPEKWIDTH,dz);
  2376. pkaspect = dz->param[SPEKWIDTH];
  2377. dz->param[SPEKBRITE] = (pkaspect/dz->param[SPEKMXASP]) * orig_brightness;
  2378. pkwidth = (dz->parray[0][vc+1]/pkaspect) * dz->nyquist;
  2379. pkwidth = min(pkwidth,2 * dz->bigfbuf[FREQ]); // Avoid -ve frqs
  2380. pkoffset = drand48() * pkwidth;
  2381. pkfrq = dz->bigfbuf[FREQ] - (pkwidth/2.0);
  2382. pkfrq += pkoffset;
  2383. dz->bigfbuf[FREQ] = (float)pkfrq;
  2384. if(dz->iparam[SPEKHARMS] > 1 && dz->param[SPEKBRITE] > 0.0) {
  2385. harmamp = dz->bigfbuf[AMPP] * dz->param[SPEKBRITE];
  2386. insert_harmonics(&peaked,&peakcnt,harmamp,orig_frequency,pkwidth,dz);
  2387. }
  2388. dz->param[SPEKBRITE] = orig_brightness;
  2389. break;
  2390. }
  2391. }
  2392. chbot += dz->chwidth;
  2393. }
  2394. if(dz->param[SPEKRANDF] > 0.0)
  2395. randomiseamps(perm,peaked,dz);
  2396. if(dz->param[SPEKSPRED] > 0)
  2397. spread_peaks(peaked,spreaddnratio,spreadupratio,dz);
  2398. if((exit_status = write_samps(dz->bigfbuf,dz->wanted,dz))<0)
  2399. return(exit_status);
  2400. dfade *= fader;
  2401. }
  2402. thistime = 0.0;
  2403. /* PAD END WITH ZEROS */
  2404. frq = 0.0;
  2405. while(thistime < 0.01) {
  2406. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc +=2) {
  2407. dz->bigfbuf[AMPP] = 0.0f;
  2408. dz->bigfbuf[FREQ] = (float)frq;
  2409. frq += dz->chwidth;
  2410. }
  2411. if((exit_status = write_samps(dz->bigfbuf,dz->wanted,dz))<0)
  2412. return(exit_status);
  2413. thistime += dz->frametime;
  2414. }
  2415. return(FINISHED);
  2416. }
  2417. /************************************** INSERT_HARMONICS ****************************************/
  2418. void insert_harmonics(int **peaked,int *peakcnt,double harmamp,float fundamental,double pkwidth,dataptr dz)
  2419. {
  2420. int n, harmchan;
  2421. double harmfrq, pkoffset;
  2422. for(n = 2;n <= dz->iparam[SPEKHARMS];n++) {
  2423. harmfrq = fundamental * (double)n;
  2424. if(dz->iparam[SPEKTYPE] == 3 || dz->iparam[SPEKTYPE] == 5) {
  2425. pkoffset = drand48() * pkwidth;
  2426. harmfrq -= (pkwidth/2.0);
  2427. harmfrq += pkoffset;
  2428. }
  2429. if(harmfrq <= fundamental)
  2430. continue;
  2431. harmchan = (int)round(harmfrq/dz->chwidth);
  2432. if(harmchan >= dz->clength || harmfrq >= dz->nyquist)
  2433. return;
  2434. (*peaked)[harmchan] = 1;
  2435. (*peakcnt)++;
  2436. dz->bigfbuf[(harmchan * 2) + 1] = (float)harmfrq;
  2437. dz->bigfbuf[harmchan * 2] = (float)harmamp;
  2438. harmamp *= dz->param[SPEKBRITE]; // Attenuate harmonics as we rise thro harmonics
  2439. }
  2440. }
  2441. /************************************** SPREAD_PEAKS ****************************************
  2442. *
  2443. * Spread peaks to the adjacent channels.
  2444. */
  2445. void spread_peaks(int *peaked,double spreaddnratio,double spreadupratio,dataptr dz)
  2446. {
  2447. int bb, cc, dd, vc;
  2448. int chanlimit;
  2449. double frqlimit, spreadval, maxwander, wander;
  2450. for(cc = 0, bb = -1,dd = 1, vc = 0; cc < dz->clength; bb++, cc++, dd++, vc +=2) {
  2451. if(dd < dz->clength) {
  2452. if(peaked[dd] && !peaked[cc]) {
  2453. chanlimit = cc - 3; // chan overlap is 8, so frq OK if lies within chans cc-3 to cc+4
  2454. if(chanlimit >= 0)
  2455. frqlimit = chanlimit * dz->chwidth; // Set downward limit of new frq as centre of chan 3-chans down
  2456. else // or at zero, if not enough channels downwards
  2457. frqlimit = 0;
  2458. spreadval = dz->bigfbuf[FREQ] * spreaddnratio; // Calculate frq of spread peak
  2459. if(spreadval <= frqlimit) { // If it exceeds limit
  2460. maxwander = dz->bigfbuf[FREQ] - frqlimit; // Calcuate gap between peak frq and downwward limit
  2461. wander = maxwander * spreaddnratio; // Calculate spread as a fraction of this gap
  2462. spreadval = dz->bigfbuf[FREQ] - wander; // Subtract spread from peak frq
  2463. }
  2464. dz->bigfbuf[(dd*2)+1] = (float)spreadval; // Set new chan frq to spreadpeak val
  2465. }
  2466. }
  2467. if(bb > 0) { // Simil, but for chan above
  2468. if(peaked[bb] && !peaked[cc]) {
  2469. chanlimit = cc + 4;
  2470. if(chanlimit < dz->clength)
  2471. frqlimit = chanlimit * dz->chwidth;
  2472. else
  2473. frqlimit = dz->nyquist;
  2474. spreadval = dz->bigfbuf[FREQ] * spreadupratio;
  2475. if(spreadval >= frqlimit) {
  2476. maxwander = frqlimit - dz->bigfbuf[FREQ];
  2477. wander = maxwander * spreaddnratio; // must use spreadDNratio to ensure new frq is below upper limit
  2478. spreadval = dz->bigfbuf[FREQ] + wander;
  2479. }
  2480. dz->bigfbuf[(bb*2)+1] = (float)spreadval;
  2481. }
  2482. }
  2483. }
  2484. }
  2485. /************************** SPECVARY **********************************/
  2486. int specvary(dataptr dz)
  2487. {
  2488. return(FINISHED);
  2489. }
  2490. /************************* SPECFORMAT *******************/
  2491. int specformat(dataptr dz)
  2492. {
  2493. int spekchans, clength, exit_status;
  2494. int n, inbrksize;
  2495. double *inbrk, frq, amp;
  2496. double chwidth, chantopfrq, chanmidfrq, chanbotfrq, chanbotamp, chanmidamp, chantopamp;
  2497. double chanmax_amp, chanmin_amp, chanmax_frq = 0.0, chanmin_frq = 0.0, chanejmin, chanejmax;
  2498. char valstr[400];
  2499. dz->brk[0] = dz->parray[0]; // Use address and pointers assigned to brktable 0
  2500. dz->brksize[0] = dz->itemcnt/2; // A param 0 is not a brktable, so not using it.
  2501. inbrk = dz->brk[0]; // This allows input data to be read using brktablread function
  2502. inbrksize = dz->itemcnt; // and param[0] to be reused for the output
  2503. spekchans = dz->iparam[SPEKPOINTS] + 2;
  2504. clength = spekchans/2;
  2505. chwidth = dz->nyquist/(double)(clength);
  2506. chantopfrq = chwidth/2.0;
  2507. chanmidfrq = 0.0;
  2508. chanbotfrq = -chantopfrq;
  2509. chanbotamp = 0.0;
  2510. if((exit_status = read_value_from_brktable(chantopfrq,0,dz))<0) // Read data from input brktable
  2511. return(exit_status);
  2512. chantopamp = dz->param[0];
  2513. chanmax_amp = 0.0; // init vals to search for min/max amps within chan
  2514. chanmin_amp = 100.0;
  2515. chanejmin = chanbotamp; // init max and min of vals at edges of channel : first channel, min at foot
  2516. chanejmax = chantopamp;
  2517. n = 0;
  2518. while(n < inbrksize) {
  2519. frq = inbrk[n++];
  2520. amp = inbrk[n++];
  2521. if(frq >= chantopfrq) { // Once frq of input data strays into next channel
  2522. if(chanmax_amp > chanejmax || chanmax_amp == 1.0) { // If peak amp in channel is greater than both edges, this is a true peak
  2523. sprintf(valstr,"%lf %lf\n",chanmax_frq,chanmax_amp); // Peak points get amp and frq of peak frq
  2524. fputs(valstr,dz->fp);
  2525. } else if(chanmin_amp < chanejmin) { // If trough amp in channel is less than both edges, this is a true trough
  2526. sprintf(valstr,"%lf %lf\n",-chanmin_frq,chanmin_amp); // Trough points get -ve of min frq in chan, and its amp
  2527. fputs(valstr,dz->fp);
  2528. } else { // Otherwise, frq to assign to channel is unknown
  2529. if((exit_status = read_value_from_brktable(chanmidfrq,0,dz))<0)
  2530. return(exit_status); // Find the amplitude at midpoint of channel
  2531. chanmidamp = dz->param[0];
  2532. sprintf(valstr,"%lf %lf\n",0.0,chanmidamp); // Store frq = 0.0 (unknown) and midchannel amp
  2533. fputs(valstr,dz->fp);
  2534. }
  2535. chanbotfrq = chantopfrq; // Move to parameters for next channel
  2536. chanmidfrq = chanmidfrq + chwidth;
  2537. chantopfrq = chanbotfrq + chwidth;
  2538. chanbotamp = chantopamp; // Finding amplitude at top edge of new channel
  2539. if((exit_status = read_value_from_brktable(chantopfrq,0,dz))<0)
  2540. return(exit_status);
  2541. chantopamp = dz->param[0];
  2542. chanejmax = max(chanbotamp,chantopamp); // find max and min of vals at edges of channel
  2543. chanejmin = min(chanbotamp,chantopamp);
  2544. chanmax_amp = 0.0; // reinit vals to search for min/max amps within chan
  2545. chanmin_amp = 100.0;
  2546. }
  2547. if(amp > chanmax_amp) { // Search for minimum and maximum amps in channel
  2548. chanmax_amp = amp; // Note amp value and frq at which it occurs
  2549. chanmax_frq = frq;
  2550. }
  2551. if(amp < chanmin_amp) {
  2552. chanmin_amp = amp;
  2553. chanmin_frq = frq;
  2554. }
  2555. }
  2556. return FINISHED;
  2557. }
  2558. /*********************** RANDOMISEAMPS ************************/
  2559. void randomiseamps(int *perm,int *peaked,dataptr dz)
  2560. {
  2561. int randvarchans, modifiedchans, chancnt, cc, vc;
  2562. double amp, atten, gain; // Get a random number of chans to attenuate
  2563. randvarchans = (int)round(drand48() * dz->param[SPEKRANDF] * (double)dz->clength);
  2564. if(randvarchans > 0) {
  2565. rndintperm(perm,dz->clength); // Generate a new random-perm of the channels
  2566. for(chancnt=0,modifiedchans=0;chancnt<dz->clength;chancnt++) {
  2567. cc = perm[chancnt]; // Proceeding through the chans in this random order,
  2568. if(!peaked[cc]) { // so long as the channel is not a peak,
  2569. vc = cc * 2;
  2570. amp = dz->bigfbuf[AMPP];
  2571. atten = dz->param[SPEKRANDA] * drand48(); // randomly attenuate its amplitude
  2572. gain = 1.0 - atten;
  2573. amp *= gain;
  2574. dz->bigfbuf[AMPP] = (float)amp;
  2575. if(++modifiedchans >= randvarchans) // quitting when enough channels have been attenuated.
  2576. break;
  2577. }
  2578. }
  2579. }
  2580. }
  2581. /*********************** RNDINTPERM ************************/
  2582. void rndintperm(int *perm,int cnt)
  2583. {
  2584. int n,t,k;
  2585. memset((char *)perm,0,cnt * sizeof(int));
  2586. for(n=0;n<cnt;n++) {
  2587. t = (int)(drand48() * (double)(n+1)); /* TRUNCATE */
  2588. if(t==n) {
  2589. for(k=n;k>0;k--)
  2590. perm[k] = perm[k-1];
  2591. perm[0] = n;
  2592. } else {
  2593. for(k=n;k>t;k--)
  2594. perm[k] = perm[k-1];
  2595. perm[t] = n;
  2596. }
  2597. }
  2598. }
  2599. /************************** GET_FLOAT_WITH_E_FROM_WITHIN_STRING **************************
  2600. * takes a pointer TO A POINTER to a string. If it succeeds in finding
  2601. * a float it returns the float value (*val), and it's new position in the
  2602. * string (*str).
  2603. */
  2604. int get_float_with_e_from_within_string(char **str,double *val)
  2605. {
  2606. char *p, *valstart;
  2607. int decimal_point_cnt = 0, has_digits = 0, has_e = 0, lastchar = 0;
  2608. p = *str;
  2609. while(isspace(*p))
  2610. p++;
  2611. valstart = p;
  2612. switch(*p) {
  2613. case('-'): break;
  2614. case('.'): decimal_point_cnt=1; break;
  2615. default:
  2616. if(!isdigit(*p))
  2617. return(FALSE);
  2618. has_digits = TRUE;
  2619. break;
  2620. }
  2621. p++;
  2622. while(!isspace(*p) && *p!=NEWLINE && *p!=ENDOFSTR) {
  2623. if(isdigit(*p))
  2624. has_digits = TRUE;
  2625. else if(*p == 'e') {
  2626. if(has_e || !has_digits)
  2627. return(FALSE);
  2628. has_e = 1;
  2629. } else if(*p == '-') {
  2630. if(!has_e || (lastchar != 'e'))
  2631. return(FALSE);
  2632. } else if(*p == '.') {
  2633. if(has_e || (++decimal_point_cnt>1))
  2634. return(FALSE);
  2635. } else
  2636. return(FALSE);
  2637. lastchar = *p;
  2638. p++;
  2639. }
  2640. if(!has_digits || sscanf(valstart,"%lf",val)!=1)
  2641. return(FALSE);
  2642. *str = p;
  2643. return(TRUE);
  2644. }
  2645. /**************************** READ_VALUE_FROM_BRKTABLE *****************************/
  2646. int read_nearest_value_from_brktable(double thistime,int paramno,dataptr dz)
  2647. {
  2648. double *endpair, *p;
  2649. double hival, loval, hiind, loind;
  2650. if(!dz->brkinit[paramno]) {
  2651. dz->brkptr[paramno] = dz->brk[paramno];
  2652. dz->firstval[paramno] = *(dz->brk[paramno]+1);
  2653. endpair = dz->brk[paramno] + ((dz->brksize[paramno]-1)*2);
  2654. dz->lastind[paramno] = *endpair;
  2655. dz->lastval[paramno] = *(endpair+1);
  2656. dz->brkinit[paramno] = 1;
  2657. }
  2658. p = dz->brkptr[paramno];
  2659. if(thistime <= *(dz->brk[paramno])) {
  2660. dz->param[paramno] = dz->firstval[paramno];
  2661. if(dz->is_int[paramno])
  2662. dz->iparam[paramno] = round(dz->param[paramno]);
  2663. return(FINISHED);
  2664. } else if(thistime >= dz->lastind[paramno]) {
  2665. dz->param[paramno] = dz->lastval[paramno];
  2666. if(dz->is_int[paramno])
  2667. dz->iparam[paramno] = round(dz->param[paramno]);
  2668. return(FINISHED);
  2669. }
  2670. if(thistime > *(p)) {
  2671. while(*(p)<thistime)
  2672. p += 2;
  2673. } else {
  2674. while(*(p)>=thistime)
  2675. p -= 2;
  2676. p += 2;
  2677. }
  2678. hival = *(p+1);
  2679. hiind = *p;
  2680. loval = *(p-1);
  2681. loind = *(p-2);
  2682. if(thistime - loind < hiind - thistime)
  2683. dz->param[paramno] = loval;
  2684. else
  2685. dz->param[paramno] = hival;
  2686. dz->brkptr[paramno] = p;
  2687. return(FINISHED);
  2688. }
  2689. /************************************* CHECK_SPEKLINE_PARAM_VALIDITY_AND_CONSISTENCY **************************/
  2690. int check_spekline_param_validity_and_consistency(dataptr dz)
  2691. {
  2692. int n;
  2693. double *data = dz->parray[0], minlevel, datrange, spekrange, frac, diff;
  2694. double minfrq = data[0], maxamp = 0.0;
  2695. double maxfrq = data[dz->itemcnt - 2];
  2696. if(minfrq < dz->param[SPEKDATLO]) {
  2697. sprintf(errstr,"Bottom-of-data frq (%lf) must be <= minimum frq in input data (%lf)\n",dz->param[SPEKDATLO],minfrq);
  2698. return DATA_ERROR;
  2699. }
  2700. if(maxfrq > dz->param[SPEKDATHI]) {
  2701. sprintf(errstr,"Top-of-data frq (%lf) must be >= maximum frq in input data (%lf)\n",dz->param[SPEKDATHI],maxfrq);
  2702. return DATA_ERROR;
  2703. }
  2704. dz->nyquist = dz->param[SPEKSRATE]/2.0;
  2705. if(dz->param[SPEKSPKHI] > dz->nyquist) {
  2706. sprintf(errstr,"Top-of-spectrum frq (%lf) cannot be above the nyquist (%lf)\n",dz->param[SPEKSPKHI],dz->nyquist);
  2707. return DATA_ERROR;
  2708. }
  2709. if(dz->param[SPEKSPKHI] <= dz->param[SPEKSPKLO]) {
  2710. sprintf(errstr,"Top-of-spectrum frq (%lf) cannot be <= bottom-of-spectrum (%lf)\n",dz->param[SPEKSPKHI],dz->param[SPEKSPKLO]);
  2711. return DATA_ERROR;
  2712. }
  2713. datrange = dz->param[SPEKDATHI] - dz->param[SPEKDATLO];
  2714. spekrange = dz->param[SPEKSPKHI] - dz->param[SPEKSPKLO];
  2715. for(n=0;n<dz->itemcnt;n+=2) { // Scale in range to outrange
  2716. frac = (data[n] - dz->param[SPEKDATLO])/datrange;
  2717. if(dz->param[SPEKWARP] != 1.0) // Warp range if requested
  2718. frac = pow(frac,dz->param[SPEKWARP]);
  2719. data[n] = (frac * spekrange) + dz->param[SPEKSPKLO];
  2720. }
  2721. if(dz->param[SPEKAWARP] != 1.0) {
  2722. for(n=1;n<dz->itemcnt;n+=2) { // Find maxamp
  2723. if(data[n] > maxamp)
  2724. maxamp = data[n];
  2725. }
  2726. for(n=1;n<dz->itemcnt;n+=2) { // Contract diff between level and max
  2727. diff = maxamp - data[n];
  2728. diff /= dz->param[SPEKAWARP];
  2729. data[n] = maxamp - diff;
  2730. }
  2731. }
  2732. if(dz->mode == 0) {
  2733. for(n=1;n<dz->itemcnt;n+=2) // Scale amps to maxamp parameter
  2734. data[n] *= dz->param[SPEKMAX];
  2735. fprintf(stdout,"INFO: Output Spectrum\n");
  2736. for(n=0;n<dz->itemcnt;n+=2)
  2737. fprintf(stdout,"INFO: %lf\t%lf\n",data[n],data[n+1]);
  2738. fflush(stdout);
  2739. minlevel = 1.0/(double)dz->infile->srate;
  2740. dz->param[SPEKBRITE] = dbtolevel(dz->param[SPEKBRITE]);
  2741. if(dz->param[SPEKBRITE] <= minlevel) {
  2742. sprintf(errstr,"Rolloff forces harmonics to effectively zero level: no effect on input sound.\n");
  2743. return(DATA_ERROR);
  2744. }
  2745. }
  2746. return FINISHED;
  2747. }
  2748. /************************************* SPECLINES **************************/
  2749. int speclines(dataptr dz) {
  2750. int exit_status, cc, vc, thisfrq, thisamp, n, harmchan;
  2751. double *data = dz->parray[0];
  2752. double thistime = 0.0, val, harmamp, harmfrq;
  2753. double frq = 0, chbot, chtop;
  2754. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc +=2) { // Write first zero level window
  2755. dz->bigfbuf[AMPP] = 0.0f;
  2756. dz->bigfbuf[FREQ] = (float)frq;
  2757. frq += dz->chwidth;
  2758. }
  2759. if((exit_status = write_samps(dz->bigfbuf,dz->wanted,dz))<0)
  2760. return(exit_status);
  2761. thistime += dz->frametime;
  2762. while(thistime < dz->param[SPEKDUR]) {
  2763. thisfrq = 0;
  2764. thisamp = 1;
  2765. chbot = -dz->chwidth;
  2766. chtop = dz->chwidth;
  2767. memset((char *)dz->bigfbuf,0,dz->wanted * sizeof(float));
  2768. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc +=2) { // Insert line spectra
  2769. if(chbot <= data[thisfrq] && chtop > data[thisfrq]) {
  2770. dz->bigfbuf[AMPP] = (float)data[thisamp];
  2771. dz->bigfbuf[FREQ] = (float)data[thisfrq];
  2772. thisfrq += 2;
  2773. thisamp += 2;
  2774. if(thisfrq >= dz->itemcnt)
  2775. break;
  2776. }
  2777. chbot += dz->chwidth;
  2778. chtop += dz->chwidth;
  2779. }
  2780. thisfrq = 0;
  2781. thisamp = 1;
  2782. chbot = -dz->chwidth;
  2783. chtop = dz->chwidth;
  2784. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc +=2) { // Broaden line spectra
  2785. if(chbot <= data[thisfrq] && chtop > data[thisfrq]) {
  2786. if(vc - 2 >= 0) {
  2787. val = (float)(data[thisamp]/3.0);
  2788. if(val > dz->bigfbuf[vc-2]) {
  2789. dz->bigfbuf[vc-2] = (float)val;
  2790. dz->bigfbuf[vc-1] = (float)(data[thisfrq]);
  2791. }
  2792. }
  2793. if(vc - 4 >= 0) {
  2794. val = (float)(data[thisamp]/10.0);
  2795. if(val > dz->bigfbuf[vc-4]) {
  2796. dz->bigfbuf[vc-4] = (float)val;
  2797. dz->bigfbuf[vc-3] = (float)(data[thisfrq]);
  2798. }
  2799. }
  2800. if(vc + 2 < dz->wanted) {
  2801. val = (float)(data[thisamp]/3.0);
  2802. if(val > dz->bigfbuf[vc+2]) {
  2803. dz->bigfbuf[vc+2] = (float)val;
  2804. dz->bigfbuf[vc+3] = (float)(data[thisfrq]);
  2805. }
  2806. }
  2807. if(vc + 4 < dz->wanted) {
  2808. val = (float)(data[thisamp]/10.0);
  2809. if(val > dz->bigfbuf[vc+4]) {
  2810. dz->bigfbuf[vc+4] = (float)val;
  2811. dz->bigfbuf[vc+5] = (float)(data[thisfrq]);
  2812. }
  2813. }
  2814. thisfrq += 2;
  2815. thisamp += 2;
  2816. if(thisfrq >= dz->itemcnt)
  2817. break;
  2818. }
  2819. chbot += dz->chwidth;
  2820. chtop += dz->chwidth;
  2821. }
  2822. if(dz->iparam[SPEKHARMS] > 1) {
  2823. harmamp = dz->param[SPEKBRITE];
  2824. for(n = 2;n <= dz->iparam[SPEKHARMS];n++) { // Add harmonics
  2825. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc +=2) {
  2826. if(dz->bigfbuf[AMPP] > 0.0) {
  2827. harmfrq = dz->bigfbuf[FREQ] * n;
  2828. harmchan = (int)round(harmfrq/dz->chwidth);
  2829. if(harmchan >= dz->clength || harmfrq >= dz->nyquist)
  2830. break;
  2831. if(dz->bigfbuf[AMPP] * harmamp > dz->bigfbuf[harmchan * 2]) {
  2832. dz->bigfbuf[(harmchan * 2) + 1] = (float)harmfrq;
  2833. dz->bigfbuf[harmchan * 2] = (float)(dz->bigfbuf[AMPP] * harmamp);
  2834. }
  2835. }
  2836. harmamp *= dz->param[SPEKBRITE]; // Attenuate harmonics as we rise thro harmonics
  2837. }
  2838. }
  2839. }
  2840. if((exit_status = write_samps(dz->bigfbuf,dz->wanted,dz))<0)
  2841. return(exit_status);
  2842. thistime += dz->frametime;
  2843. }
  2844. dz->infile->origstype = 0;
  2845. return FINISHED;
  2846. }
  2847. /******************************** DBTOLEVEL ***********************/
  2848. double dbtolevel(double val)
  2849. {
  2850. int isneg = 0;
  2851. if(flteq(val,0.0))
  2852. return(1.0);
  2853. if(val < 0.0) {
  2854. val = -val;
  2855. isneg = 1;
  2856. }
  2857. val /= 20.0;
  2858. val = pow(10.0,val);
  2859. if(isneg)
  2860. val = 1.0/val;
  2861. return(val);
  2862. }
  2863. /****************************** GET_MODE *********************************/
  2864. int get_the_mode_from_cmdline(char *str,dataptr dz)
  2865. {
  2866. char temp[200], *p;
  2867. if(sscanf(str,"%s",temp)!=1) {
  2868. sprintf(errstr,"Cannot read mode of program.\n");
  2869. return(USAGE_ONLY);
  2870. }
  2871. p = temp + strlen(temp) - 1;
  2872. while(p >= temp) {
  2873. if(!isdigit(*p)) {
  2874. fprintf(stderr,"Invalid mode of program entered.\n");
  2875. return(USAGE_ONLY);
  2876. }
  2877. p--;
  2878. }
  2879. if(sscanf(str,"%d",&dz->mode)!=1) {
  2880. fprintf(stderr,"Cannot read mode of program.\n");
  2881. return(USAGE_ONLY);
  2882. }
  2883. if(dz->mode <= 0 || dz->mode > dz->maxmode) {
  2884. fprintf(stderr,"Program mode value [%d] is out of range [1 - %d].\n",dz->mode,dz->maxmode);
  2885. return(USAGE_ONLY);
  2886. }
  2887. dz->mode--; /* CHANGE TO INTERNAL REPRESENTATION OF MODE NO */
  2888. return(FINISHED);
  2889. }
  2890. /************************************* SPECLINESFILT **************************/
  2891. int speclinesfilt(dataptr dz)
  2892. {
  2893. double thismidi, thisamp;
  2894. int n;
  2895. double *data = dz->parray[0];
  2896. char temp[20000], temp2[128];
  2897. strcpy(temp,"0");
  2898. for(n=0;n<dz->itemcnt;n+=2) {
  2899. thismidi = unchecked_hztomidi(data[n]);
  2900. thisamp = data[n+1];
  2901. sprintf(temp2," %lf %lf",thismidi,thisamp);
  2902. strcat(temp,temp2);
  2903. }
  2904. strcat(temp,"\n");
  2905. if(fputs(temp,dz->fp)<0) {
  2906. sprintf(errstr,"FAILED TO WRITE FILTER DATA TO FILE\n");
  2907. return SYSTEM_ERROR;
  2908. }
  2909. sprintf(temp,"%lf",dz->param[SPEKDUR]);
  2910. for(n=0;n<dz->itemcnt;n+=2) {
  2911. thismidi = unchecked_hztomidi(data[n]);
  2912. thisamp = data[n+1];
  2913. sprintf(temp2," %lf %lf",thismidi,thisamp);
  2914. strcat(temp,temp2);
  2915. }
  2916. strcat(temp,"\n");
  2917. if(fputs(temp,dz->fp)<0) {
  2918. sprintf(errstr,"FAILED TO WRITE FILTER DATA TO FILE\n");
  2919. return SYSTEM_ERROR;
  2920. }
  2921. return FINISHED;
  2922. }
  2923. //RWD 2025 zero error checking - will already have been done!
  2924. static int checkchans4format(int chans, const char* fname)
  2925. {
  2926. char *lastdot;
  2927. lastdot = strrchr(fname,'.');
  2928. if(chans > 8192){
  2929. if((_stricmp(lastdot,".wav")==0)
  2930. || (_stricmp(lastdot,".ana")==0))
  2931. return 0;
  2932. }
  2933. return 1;
  2934. }