libcm is a C development framework with an emphasis on audio signal processing applications.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

cmProc2.c 170KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723
  1. #include "cmPrefix.h"
  2. #include "cmGlobal.h"
  3. #include "cmRpt.h"
  4. #include "cmErr.h"
  5. #include "cmCtx.h"
  6. #include "cmMem.h"
  7. #include "cmMallocDebug.h"
  8. #include "cmLinkedHeap.h"
  9. #include "cmSymTbl.h"
  10. #include "cmFloatTypes.h"
  11. #include "cmComplexTypes.h"
  12. #include "cmFile.h"
  13. #include "cmFileSys.h"
  14. #include "cmProcObj.h"
  15. #include "cmProcTemplate.h"
  16. #include "cmAudioFile.h"
  17. #include "cmMath.h"
  18. #include "cmProc.h"
  19. #include "cmVectOps.h"
  20. #include "cmKeyboard.h"
  21. #include "cmGnuPlot.h"
  22. #include "cmTime.h"
  23. #include "cmMidi.h"
  24. #include "cmProc2.h"
  25. //------------------------------------------------------------------------------------------------------------
  26. cmArray* cmArrayAllocate( cmCtx* c, cmArray* ap, unsigned eleCnt, unsigned eleByteCnt, unsigned flags )
  27. {
  28. cmArray* p = cmObjAlloc( cmArray, c, ap );
  29. if( eleCnt > 0 && eleByteCnt > 0 )
  30. if( cmArrayInit(p, eleCnt, eleByteCnt, flags ) != cmOkRC )
  31. cmArrayFree(&p);
  32. return cmOkRC;
  33. }
  34. cmRC_t cmArrayFree( cmArray** pp )
  35. {
  36. cmRC_t rc = cmOkRC;
  37. cmArray* p = *pp;
  38. if( pp == NULL || *pp == NULL )
  39. return cmOkRC;
  40. if((rc = cmArrayFinal(p)) != cmOkRC )
  41. return rc;
  42. cmMemPtrFree(&p->ptr);
  43. cmObjFree(pp);
  44. return rc;
  45. }
  46. cmRC_t cmArrayInit( cmArray* p, unsigned eleCnt, unsigned eleByteCnt, unsigned flags )
  47. {
  48. cmRC_t rc = cmOkRC;
  49. if((rc = cmArrayFinal(p)) != cmOkRC )
  50. return rc;
  51. p->allocByteCnt = eleCnt * eleByteCnt;
  52. p->ptr = cmIsFlag(flags,kZeroArrayFl) ? cmMemResizeZ( char, p->ptr, p->allocByteCnt ) : cmMemResize( char, p->ptr, p->allocByteCnt );
  53. p->eleCnt = eleCnt;
  54. p->eleByteCnt = eleByteCnt;
  55. return rc;
  56. }
  57. cmRC_t cmArrayFinal( cmArray* p )
  58. { return cmOkRC; }
  59. char* cmArrayReallocDestroy(cmArray* p, unsigned newEleCnt, unsigned newEleByteCnt, unsigned flags )
  60. {
  61. // if memory is expanding
  62. if( newEleCnt * newEleByteCnt > p->allocByteCnt )
  63. cmArrayInit( p, newEleCnt, newEleByteCnt, flags );
  64. else
  65. {
  66. // ... otherwise memory is contrcmting
  67. p->eleCnt = newEleCnt;
  68. p->eleByteCnt = newEleByteCnt;
  69. if( cmIsFlag( flags, kZeroArrayFl ))
  70. memset(p->ptr,0,p->eleByteCnt);
  71. }
  72. return p->ptr;
  73. }
  74. void cmArrayReallocDestroyV(cmArray* p, int eleByteCnt,unsigned flags, ... )
  75. {
  76. unsigned i;
  77. unsigned eleCnt = 0;
  78. unsigned argCnt = 0;
  79. va_list vl0,vl1;
  80. assert(eleByteCnt>0);
  81. va_start(vl0,flags);
  82. va_copy(vl1,vl0);
  83. while( va_arg(vl0,void**) != NULL )
  84. {
  85. int argEleCnt = va_arg(vl0,int);
  86. assert(argEleCnt>0);
  87. eleCnt += argEleCnt;
  88. ++argCnt;
  89. }
  90. va_end(vl0);
  91. char* a = cmArrayReallocDestroy(p,eleCnt,eleByteCnt,flags);
  92. for(i=0; i<argCnt; ++i)
  93. {
  94. void** vp = va_arg(vl1,void**);
  95. unsigned n = va_arg(vl1,unsigned);
  96. *vp = a;
  97. a += n*eleByteCnt;
  98. }
  99. va_end(vl1);
  100. }
  101. char* cmArrayReallocPreserve(cmArray* p, unsigned newEleCnt, unsigned newEleByteCnt, unsigned flags )
  102. {
  103. unsigned cn = p->eleCnt * p->eleByteCnt;
  104. unsigned dn = newEleCnt * newEleByteCnt;
  105. if( dn > p->allocByteCnt )
  106. p->allocByteCnt = dn;
  107. p->ptr = cmIsFlag(flags,kZeroArrayFl ) ? cmMemResizePZ( char, p->ptr, cn ) : cmMemResizeP( char, p->ptr, cn);
  108. p->eleCnt = newEleCnt;
  109. p->eleByteCnt= newEleByteCnt;
  110. return p->ptr;
  111. }
  112. //------------------------------------------------------------------------------------------------------------
  113. cmAudioFileWr* cmAudioFileWrAlloc( cmCtx* c, cmAudioFileWr* ap, unsigned procSmpCnt, const char* fn, double srate, unsigned chCnt, unsigned bitsPerSample )
  114. {
  115. cmAudioFileWr* p = cmObjAlloc( cmAudioFileWr, c, ap );
  116. if( cmAudioFileWrInit( p, procSmpCnt, fn, srate, chCnt, bitsPerSample ) != cmOkRC )
  117. cmObjFree(&p);
  118. return p;
  119. }
  120. cmRC_t cmAudioFileWrFree( cmAudioFileWr** pp )
  121. {
  122. cmRC_t rc = cmOkRC;
  123. if( pp != NULL && *pp != NULL )
  124. {
  125. cmAudioFileWr* p = *pp;
  126. if((rc = cmAudioFileWrFinal(p)) == cmOkRC )
  127. {
  128. cmMemPtrFree(&p->bufV);
  129. cmMemPtrFree(&p->fn );
  130. cmObjFree(pp);
  131. }
  132. }
  133. return rc;
  134. }
  135. cmRC_t cmAudioFileWrInit( cmAudioFileWr* p, unsigned procSmpCnt, const char* fn, double srate, unsigned chCnt, unsigned bitsPerSample )
  136. {
  137. cmRC_t rc;
  138. cmRC_t afRC;
  139. if((rc = cmAudioFileWrFinal( p)) != cmOkRC )
  140. return rc;
  141. p->h = cmAudioFileNewCreate( fn, srate, bitsPerSample, chCnt, &afRC, p->obj.err.rpt );
  142. if( afRC != kOkAfRC )
  143. return cmCtxRtCondition( &p->obj, afRC, "Unable to open the audio file:'%s'", fn );
  144. p->bufV = cmMemResize( cmSample_t, p->bufV, procSmpCnt * chCnt );
  145. p->procSmpCnt = procSmpCnt;
  146. p->chCnt = chCnt;
  147. p->curChCnt = 0;
  148. p->fn = cmMemResizeZ( cmChar_t, p->fn, strlen(fn)+1 );
  149. strcpy(p->fn,fn);
  150. return rc;
  151. }
  152. cmRC_t cmAudioFileWrFinal( cmAudioFileWr* p )
  153. {
  154. cmRC_t afRC;
  155. if( p != NULL )
  156. {
  157. if( cmAudioFileIsValid( p->h ) )
  158. if(( afRC = cmAudioFileDelete( &p->h )) != kOkAfRC )
  159. return cmCtxRtCondition( &p->obj, afRC, "Unable to close the audio file:'%s'", p->fn );
  160. }
  161. return cmOkRC;
  162. }
  163. cmRC_t cmAudioFileWrExec( cmAudioFileWr* p, unsigned chIdx, const cmSample_t* sp, unsigned sn )
  164. {
  165. cmRC_t afRC;
  166. assert( sn <= p->procSmpCnt && chIdx < p->chCnt );
  167. cmSample_t* buf = p->bufV + (chIdx * p->procSmpCnt);
  168. cmVOS_Copy( buf, sn, sp);
  169. if( sn < p->procSmpCnt )
  170. cmVOS_Fill( buf+sn, p->procSmpCnt-sn, 0 );
  171. p->curChCnt++;
  172. if( p->curChCnt == p->chCnt )
  173. {
  174. p->curChCnt = 0;
  175. cmSample_t* bufPtrPtr[ p->chCnt ];
  176. unsigned i = 0;
  177. for(i=0; i<p->chCnt; ++i)
  178. bufPtrPtr[i] = p->bufV + (i*p->procSmpCnt);
  179. if((afRC = cmAudioFileWriteSample( p->h, p->procSmpCnt, p->chCnt, bufPtrPtr )) != kOkAfRC )
  180. return cmCtxRtCondition( &p->obj, afRC, "Write failed on audio file:'%s'", p->fn );
  181. }
  182. return cmOkRC;
  183. }
  184. void cmAudioFileWrTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH )
  185. {
  186. const char* fn = "/home/kevin/src/cm/test0.aif";
  187. double durSecs = 10;
  188. double srate = 44100;
  189. unsigned chCnt = 2;
  190. unsigned bitsPerSmp = 16;
  191. unsigned procSmpCnt = 64;
  192. double hz = 1000;
  193. unsigned overToneCnt= 1;
  194. unsigned smpCnt = durSecs * srate;
  195. unsigned i;
  196. cmCtx* c = cmCtxAlloc( NULL, rpt, lhH, stH );
  197. cmSigGen* sgp = cmSigGenAlloc( c, NULL, procSmpCnt, srate, kWhiteWfId, hz, overToneCnt );
  198. cmAudioFileWr* awp = cmAudioFileWrAlloc( c, NULL, procSmpCnt, fn, srate, chCnt, bitsPerSmp );
  199. for(i=0; i<smpCnt; ++i)
  200. {
  201. cmSigGenExec( sgp );
  202. cmAudioFileWrExec( awp, 0, sgp->outV, sgp->outN );
  203. cmAudioFileWrExec( awp, 1, sgp->outV, sgp->outN );
  204. i += sgp->outN;
  205. }
  206. printf("Frames:%i\n",smpCnt);
  207. cmAudioFileWrFree(&awp);
  208. cmSigGenFree( &sgp );
  209. cmCtxFree(&c);
  210. cmAudioFileReportFn( fn, 0, 20, rpt );
  211. }
  212. //------------------------------------------------------------------------------------------------------------
  213. cmMatrixBuf* cmMatrixBufAllocFile( cmCtx* c, cmMatrixBuf* p, const char* fn )
  214. {
  215. cmRC_t rc;
  216. cmMatrixBuf* op = cmObjAlloc( cmMatrixBuf, c, p );
  217. if( fn != NULL )
  218. if((rc = cmMatrixBufInitFile(op,fn)) != cmOkRC )
  219. cmObjFree(&op);
  220. return op;
  221. }
  222. cmMatrixBuf* cmMatrixBufAllocCopy(cmCtx* c, cmMatrixBuf* p, unsigned rn, unsigned cn, const cmSample_t* sp )
  223. {
  224. cmRC_t rc;
  225. cmMatrixBuf* op = cmObjAlloc( cmMatrixBuf, c, p );
  226. if( sp != NULL && rn > 0 && cn > 0 )
  227. if((rc = cmMatrixBufInitCopy(op,rn,cn,sp)) != cmOkRC )
  228. cmObjFree(&op);
  229. return op;
  230. }
  231. cmMatrixBuf* cmMatrixBufAlloc( cmCtx* c, cmMatrixBuf* p, unsigned rn, unsigned cn )
  232. {
  233. cmRC_t rc;
  234. cmMatrixBuf* op = cmObjAlloc( cmMatrixBuf, c, p );
  235. if( rn > 0 && cn > 0 )
  236. if((rc = cmMatrixBufInit(op,rn,cn)) != cmOkRC )
  237. cmObjFree(&op);
  238. return op;
  239. }
  240. cmRC_t cmMatrixBufFree( cmMatrixBuf** pp )
  241. {
  242. cmRC_t rc = cmOkRC;
  243. if( pp != NULL && *pp != NULL )
  244. {
  245. cmMatrixBuf* p = *pp;
  246. if((rc = cmMatrixBufFinal(p)) == cmOkRC )
  247. {
  248. cmMemPtrFree(&p->bufPtr);
  249. cmObjFree(pp);
  250. }
  251. }
  252. return rc;
  253. }
  254. void _cmMatrixBufGetFileSize( FILE* fp, unsigned* lineCharCntPtr, unsigned* lineCntPtr )
  255. {
  256. *lineCharCntPtr = 0;
  257. *lineCntPtr = 0;
  258. while( !feof(fp) )
  259. {
  260. char ch;
  261. unsigned charCnt = 0;
  262. while( (ch = getc(fp)) != EOF )
  263. {
  264. charCnt++;
  265. if( ch == '\n' )
  266. break;
  267. }
  268. *lineCntPtr += 1;
  269. if(charCnt > *lineCharCntPtr )
  270. *lineCharCntPtr = charCnt;
  271. }
  272. *lineCharCntPtr += 5; // add a safety margin
  273. }
  274. cmRC_t _cmMatrixBufGetMatrixSize( cmObj* op, FILE* fp, unsigned lineCharCnt, unsigned lineCnt, unsigned* rowCntPtr, unsigned * colCntPtr, const char* fn )
  275. {
  276. unsigned i;
  277. char lineBuf[ lineCharCnt + 1 ];
  278. *rowCntPtr = 0;
  279. *colCntPtr = 0;
  280. for(i=0; i<lineCnt; ++i)
  281. {
  282. if(fgets(lineBuf,lineCharCnt,fp)==NULL)
  283. {
  284. // if the last line is blank then return from here
  285. if( feof(fp) )
  286. return cmOkRC;
  287. return cmCtxRtCondition( op, cmSystemErrorRC, "A read error occured on the matrix file:'%s'.",fn);
  288. }
  289. assert( strlen(lineBuf) < lineCharCnt );
  290. char* lp = lineBuf;
  291. char* tp;
  292. // eat any leading white space
  293. while( (*lp) && isspace(*lp) )
  294. ++lp;
  295. // if the line was blank then skip it
  296. if( strlen(lp) == 0 || *lp == '#' )
  297. continue;
  298. (*rowCntPtr) += 1;
  299. unsigned colCnt;
  300. for(colCnt=0; (tp = strtok(lp," ")) != NULL; ++colCnt )
  301. lp = NULL;
  302. if( colCnt > *colCntPtr )
  303. *colCntPtr = colCnt;
  304. }
  305. return cmOkRC;
  306. }
  307. double _cmMatrixBufStrToNum( cmObj* op, const char* cp )
  308. {
  309. double v;
  310. if( sscanf(cp,"%le ",&v) != 1 )
  311. cmCtxRtCondition( op, cmArgAssertRC, "Parse error reading matrix file.");
  312. return v;
  313. }
  314. cmRC_t _cmMatrixBufReadFile(cmObj* op, FILE* fp, cmSample_t* p, unsigned lineCharCnt, unsigned rn, unsigned cn)
  315. {
  316. char lineBuf[ lineCharCnt+1 ];
  317. unsigned ci = 0;
  318. unsigned ri = 0;
  319. while( fgets(lineBuf,lineCharCnt,fp) != NULL )
  320. {
  321. char* lp = lineBuf;
  322. char* tp;
  323. while( (*lp) && isspace(*lp) )
  324. lp++;
  325. if( strlen(lp) == 0 || *lp == '#' )
  326. continue;
  327. for(ci=0; (tp = strtok(lp," ")) != NULL; ++ci )
  328. {
  329. p[ (ci*rn) + ri ] = _cmMatrixBufStrToNum(op,tp); //atof(tp);
  330. lp = NULL;
  331. }
  332. ++ri;
  333. }
  334. return cmOkRC;
  335. }
  336. cmRC_t cmMatrixBufInitFile( cmMatrixBuf* p, const char* fn )
  337. {
  338. cmRC_t rc;
  339. FILE* fp;
  340. unsigned lineCharCnt;
  341. unsigned lineCnt;
  342. unsigned rn;
  343. unsigned cn;
  344. if((fp = fopen(fn,"rt")) == NULL )
  345. return cmCtxRtCondition( &p->obj, cmSystemErrorRC, "Unable to open the matrix file:'%s'", fn );
  346. // get the length of the longest line in the file
  347. _cmMatrixBufGetFileSize(fp,&lineCharCnt,&lineCnt);
  348. rewind(fp);
  349. // get the count of matrix rows and columns
  350. if((rc=_cmMatrixBufGetMatrixSize( &p->obj, fp, lineCharCnt, lineCnt, &rn, &cn, fn )) != cmOkRC )
  351. goto errLabel;
  352. rewind(fp);
  353. // allocate the matrix memory
  354. cmMatrixBufInit(p,rn,cn);
  355. // fill the matrix from the file
  356. rc = _cmMatrixBufReadFile(&p->obj,fp,p->bufPtr,lineCharCnt,rn,cn);
  357. errLabel:
  358. if( rc != cmOkRC )
  359. cmMatrixBufFinal(p);
  360. fclose(fp);
  361. return rc;
  362. }
  363. cmRC_t cmMatrixBufInitCopy( cmMatrixBuf* p, unsigned rn, unsigned cn, const cmSample_t* sp )
  364. {
  365. cmRC_t rc;
  366. if((rc = cmMatrixBufInit(p,rn,cn)) != cmOkRC )
  367. return rc;
  368. cmVOS_Copy(p->bufPtr,(rn*cn),sp);
  369. return rc;
  370. }
  371. cmRC_t cmMatrixBufInit( cmMatrixBuf* p, unsigned rn, unsigned cn )
  372. {
  373. cmRC_t rc;
  374. if((rc = cmMatrixBufFinal(p)) != cmOkRC )
  375. return rc;
  376. p->rn = rn;
  377. p->cn = cn;
  378. p->bufPtr = cmMemResize( cmSample_t, p->bufPtr, rn*cn );
  379. return cmOkRC;
  380. }
  381. cmRC_t cmMatrixBufFinal( cmMatrixBuf* p )
  382. { return cmOkRC; }
  383. cmSample_t* cmMatrixBufColPtr( cmMatrixBuf* p, unsigned ci )
  384. { assert(ci<p->cn); return p->bufPtr + (ci * p->rn); }
  385. cmSample_t* cmMatrixBufRowPtr( cmMatrixBuf* p, unsigned ri )
  386. { assert(ri<p->rn); return p->bufPtr + ri; }
  387. void cmMatrixBufTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH )
  388. {
  389. cmSample_t v[] = {1,2,2,3};
  390. cmCtx* c = cmCtxAlloc(NULL,rpt,lhH,stH);
  391. cmMatrixBuf* mbp = cmMatrixBufAllocFile(c, NULL, "temp.mat" );
  392. cmMatrixBuf* vbp = cmMatrixBufAllocCopy(c, NULL, 4,1,v);
  393. unsigned i;
  394. printf("rn:%i cn:%i\n",mbp->rn,mbp->cn);
  395. //cmVOS_Print( stdout, 10, 10, mbp->bufPtr );
  396. printf("%.1f\n ",cmVOS_Median( cmMatrixBufColPtr(vbp,0),vbp->rn));
  397. for(i=0; i<mbp->cn; ++i)
  398. {
  399. //cmVOS_Print( stdout, 1, mbp->cn, cmMatrixBufColPtr(c,mbp,i) );
  400. printf("%.1f, ",cmVOS_Median( cmMatrixBufColPtr(mbp,i),mbp->rn));
  401. }
  402. printf("\n");
  403. cmMatrixBufFree(&mbp);
  404. cmMatrixBufFree(&vbp);
  405. cmCtxFree(&c);
  406. }
  407. //------------------------------------------------------------------------------------------------------------
  408. cmSigGen* cmSigGenAlloc( cmCtx* c, cmSigGen* p, unsigned procSmpCnt, double srate, unsigned wfId, double fundFrqHz, unsigned overToneCnt )
  409. {
  410. cmSigGen* op = cmObjAlloc( cmSigGen, c, p );
  411. if( procSmpCnt > 0 && srate > 0 && wfId != kInvalidWfId )
  412. if( cmSigGenInit( op, procSmpCnt, srate, wfId, fundFrqHz, overToneCnt ) != cmOkRC )
  413. cmObjFree(&op);
  414. return op;
  415. }
  416. cmRC_t cmSigGenFree( cmSigGen** pp )
  417. {
  418. cmRC_t rc = cmOkRC;
  419. if( pp != NULL && *pp != NULL )
  420. {
  421. cmSigGen* p = *pp;
  422. if((rc = cmSigGenFinal(p)) == cmOkRC )
  423. {
  424. cmMemPtrFree(&p->outV);
  425. cmObjFree(pp);
  426. }
  427. }
  428. return rc;
  429. }
  430. cmRC_t cmSigGenInit( cmSigGen* p, unsigned procSmpCnt, double srate, unsigned wfId, double fundFrqHz, unsigned overToneCnt )
  431. {
  432. assert( srate > 0 && procSmpCnt > 0 );
  433. p->outV = cmMemResize( cmSample_t, p->outV, procSmpCnt );
  434. p->outN = procSmpCnt;
  435. p->wfId = wfId;
  436. p->overToneCnt = overToneCnt;
  437. p->fundFrqHz = fundFrqHz;
  438. p->phase = 0;
  439. p->delaySmp = 0;
  440. p->srate = srate;
  441. return cmOkRC;
  442. }
  443. cmRC_t cmSigGenFinal( cmSigGen* p )
  444. { return cmOkRC; }
  445. cmRC_t cmSigGenExec( cmSigGen* p )
  446. {
  447. switch( p->wfId )
  448. {
  449. case kSineWfId: p->phase = cmVOS_SynthSine( p->outV, p->outN, p->phase, p->srate, p->fundFrqHz ); break;
  450. case kCosWfId: p->phase = cmVOS_SynthCosine( p->outV, p->outN, p->phase, p->srate, p->fundFrqHz ); break;
  451. case kSquareWfId: p->phase = cmVOS_SynthSquare( p->outV, p->outN, p->phase, p->srate, p->fundFrqHz, p->overToneCnt ); break;
  452. case kTriangleWfId: p->phase = cmVOS_SynthTriangle( p->outV, p->outN, p->phase, p->srate, p->fundFrqHz, p->overToneCnt ); break;
  453. case kSawtoothWfId: p->phase = cmVOS_SynthSawtooth( p->outV, p->outN, p->phase, p->srate, p->fundFrqHz, p->overToneCnt ); break;
  454. case kWhiteWfId: cmVOS_Random( p->outV, p->outN, -1.0, 1.0 ); break;
  455. case kPinkWfId: p->delaySmp = cmVOS_SynthPinkNoise(p->outV, p->outN, p->delaySmp ); break;
  456. case kPulseWfId: p->phase = cmVOS_SynthPulseCos( p->outV, p->outN, p->phase, p->srate, p->fundFrqHz, p->overToneCnt ); break;
  457. case kImpulseWfId: p->phase = cmVOS_SynthImpulse( p->outV, p->outN, p->phase, p->srate, p->fundFrqHz ); break;
  458. case kSilenceWfId: cmVOS_Fill( p->outV, p->outN, 0 ); break;
  459. case kPhasorWfId: p->phase = cmVOS_SynthPhasor( p->outV, p->outN, p->phase, p->srate, p->fundFrqHz ); break;
  460. case kSeqWfId: p->phase = cmVOS_Seq( p->outV, p->outN, p->phase, 1 ); break;
  461. case kInvalidWfId:
  462. default:
  463. return cmCtxRtAssertFailed( &p->obj, 0, "Invalid waveform shape.");
  464. }
  465. return cmOkRC;
  466. }
  467. //------------------------------------------------------------------------------------------------------------
  468. cmDelay* cmDelayAlloc( cmCtx* c, cmDelay* ap, unsigned procSmpCnt, unsigned delaySmpCnt )
  469. {
  470. cmDelay* p = cmObjAlloc( cmDelay, c, ap );
  471. if( procSmpCnt > 0 && delaySmpCnt > 0 )
  472. if( cmDelayInit( p,procSmpCnt,delaySmpCnt) != cmOkRC && ap == NULL )
  473. cmObjFree(&p);
  474. return p;
  475. }
  476. cmRC_t cmDelayFree( cmDelay** pp )
  477. {
  478. cmRC_t rc = cmOkRC;
  479. if( pp != NULL && *pp != NULL )
  480. {
  481. cmDelay* p = *pp;
  482. if((rc = cmDelayFinal(*pp)) == cmOkRC )
  483. {
  484. cmMemPtrFree(&p->bufPtr);
  485. cmObjFree(pp);
  486. }
  487. }
  488. return rc;
  489. }
  490. cmRC_t cmDelayInit( cmDelay* p, unsigned procSmpCnt, unsigned delaySmpCnt )
  491. {
  492. p->procSmpCnt = procSmpCnt;
  493. p->delaySmpCnt = delaySmpCnt;
  494. p->bufSmpCnt = delaySmpCnt + procSmpCnt;
  495. p->bufPtr = cmMemResizeZ( cmSample_t, p->bufPtr, p->bufSmpCnt);
  496. p->delayInIdx = 0;
  497. p->outCnt = 1;
  498. p->outV[0] = p->bufPtr;
  499. p->outN[0] = p->procSmpCnt;
  500. p->outV[1] = NULL;
  501. p->outN[1] = 0;
  502. return cmOkRC;
  503. }
  504. cmRC_t cmDelayFinal( cmDelay* p )
  505. { return cmOkRC; }
  506. cmRC_t cmDelayCopyIn( cmDelay* p, const cmSample_t* sp, unsigned sn )
  507. {
  508. assert(sn<=p->procSmpCnt);
  509. unsigned n0 = cmMin(sn,p->bufSmpCnt - p->delayInIdx);
  510. // copy as many samples as possible from the input to the delayInIdx
  511. cmVOS_Copy(p->bufPtr + p->delayInIdx, n0, sp);
  512. p->delayInIdx = (p->delayInIdx + n0) % p->bufSmpCnt;
  513. // if there was not enough room to copy all the samples into the end of the buffer ....
  514. if( n0 < sn )
  515. {
  516. assert( p->delayInIdx == 0 );
  517. // ... then copy the rest to the beginning of the buffer
  518. unsigned n1 = sn - n0;
  519. cmVOS_Copy(p->bufPtr,n1, sp + n0 );
  520. p->delayInIdx = (p->delayInIdx + n1) % p->bufSmpCnt;
  521. }
  522. return cmOkRC;
  523. }
  524. cmRC_t cmDelayAdvance( cmDelay* p, unsigned sn )
  525. {
  526. // advance the output by sn and make sn samples available
  527. int delayOutIdx = ((p->outV[0] - p->bufPtr) + sn) % p->bufSmpCnt;
  528. p->outV[0] = p->bufPtr + delayOutIdx;
  529. p->outN[0] = cmMin(p->bufSmpCnt - delayOutIdx , sn );
  530. p->outCnt = p->outN[0] == sn ? 1 : 2 ;
  531. p->outV[1] = p->outCnt == 1 ? NULL : p->bufPtr;
  532. p->outN[1] = p->outCnt == 1 ? 0 : sn - p->outN[0];
  533. return cmOkRC;
  534. }
  535. cmRC_t cmDelayExec( cmDelay* p, const cmSample_t* sp, unsigned sn, bool bypassFl )
  536. {
  537. cmRC_t rc = cmOkRC;
  538. if( bypassFl )
  539. memcpy(p->outV,sp,sn*sizeof(cmSample_t));
  540. else
  541. {
  542. cmDelayCopyIn(p,sp,sn);
  543. rc = cmDelayAdvance(p,sn);
  544. }
  545. return rc;
  546. }
  547. void cmDelayTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH )
  548. {
  549. cmCtx ctx;
  550. cmDelay delay;
  551. cmSigGen sigGen;
  552. unsigned procCnt = 4;
  553. unsigned procSmpCnt = 5;
  554. unsigned delaySmpCnt = 3;
  555. unsigned i;
  556. cmCtx* c = cmCtxAlloc( &ctx, rpt, lhH, stH );
  557. cmDelay* dlp = cmDelayAlloc( c, &delay, procSmpCnt, delaySmpCnt );
  558. cmSigGen* sgp = cmSigGenAlloc( c, &sigGen, procSmpCnt, 0, kSeqWfId,0, 0);
  559. for(i=0; i<procCnt; ++i)
  560. {
  561. cmSigGenExec(sgp);
  562. cmDelayExec(dlp,sgp->outV,sgp->outN,false);
  563. //cmVOS_Print( c->outFp, 1, sgp->outN, sgp->outV, 5, 0 );
  564. cmCtxPrint(c,"%i %i : ",i,0);
  565. cmVOS_PrintE( rpt, 1, dlp->outN[0], dlp->outV[0] );
  566. if( dlp->outN[1] > 0 )
  567. {
  568. cmCtxPrint(c,"%i %i : ",i,1);
  569. cmVOS_PrintE( rpt, 1, dlp->outN[1], dlp->outV[1] );
  570. }
  571. }
  572. cmSigGenFinal(sgp);
  573. cmDelayFinal(dlp);
  574. cmCtxFinal(c);
  575. }
  576. //------------------------------------------------------------------------------------------------------------
  577. cmFIR* cmFIRAllocKaiser(cmCtx* c, cmFIR* p, unsigned procSmpCnt, double srate, double passHz, double stopHz, double passDb, double stopDb, unsigned flags )
  578. {
  579. cmFIR* op = cmObjAlloc( cmFIR, c, p );
  580. if( procSmpCnt > 0 && srate > 0 )
  581. if( cmFIRInitKaiser(op,procSmpCnt,srate,passHz,stopHz,passDb,stopDb,flags) != cmOkRC )
  582. cmObjFree(&op);
  583. return op;
  584. }
  585. cmFIR* cmFIRAllocSinc( cmCtx* c, cmFIR* p, unsigned procSmpCnt, double srate, unsigned sincSmpCnt, double fcHz, unsigned flags, const double* wndV )
  586. {
  587. cmFIR* op = cmObjAlloc( cmFIR, c, p );
  588. if( srate > 0 && sincSmpCnt > 0 )
  589. if( cmFIRInitSinc(op,procSmpCnt,srate,sincSmpCnt,fcHz,flags,wndV) != cmOkRC )
  590. cmObjFree(&op);
  591. return op;
  592. }
  593. cmRC_t cmFIRFree( cmFIR** pp )
  594. {
  595. cmRC_t rc = cmOkRC;
  596. if( pp != NULL && *pp != NULL)
  597. {
  598. cmFIR* p = *pp;
  599. if((rc = cmFIRFinal(*pp)) == cmOkRC )
  600. {
  601. cmMemPtrFree(&p->coeffV);
  602. cmMemPtrFree(&p->outV);
  603. cmMemPtrFree(&p->delayV);
  604. cmObjFree(pp);
  605. }
  606. }
  607. return rc;
  608. }
  609. cmRC_t cmFIRInitKaiser( cmFIR* p, unsigned procSmpCnt, double srate, double passHz, double stopHz, double passDb, double stopDb, unsigned flags )
  610. {
  611. // pass/stop frequencies above nyquist produce incorrect results
  612. assert( passHz <= srate/2 && stopHz<=srate/2);
  613. // based on Orfandis, Introduction to Signal Processing, p.551 Prentice Hall, 1996
  614. double fcHz = (passHz + stopHz) / 2; // fc is half way between passHz and stopHz
  615. double dHz = fabs(stopHz-passHz);
  616. // convert ripple spec from db to linear
  617. double dPass = (pow(10,passDb/20)-1) / (pow(10,passDb/20)+1);
  618. double dStop = pow(10,-stopDb/20);
  619. // in practice the ripple must be equal in the stop and pass band - so take the minimum between the two
  620. double d = cmMin(dPass,dStop);
  621. // convert the ripple bcmk to db
  622. double A = -20 * log10(d);
  623. // compute the kaiser alpha coeff
  624. double alpha = 0;
  625. if( A >= 50.0 ) // for ripple > 50
  626. alpha = 0.1102 * (A-8.7);
  627. else // for ripple <= 21
  628. {
  629. if( A > 21 )
  630. alpha = (0.5842 * (pow(A-21.0,0.4))) + (0.07886*(A-21));
  631. }
  632. double D = 0.922;
  633. if( A > 21 )
  634. D = (A - 7.95) / 14.36;
  635. // compute the filter order
  636. unsigned N = (unsigned)(floor(D * srate / dHz) + 1);
  637. //if N is even
  638. if( cmIsEvenU(N) )
  639. N = N + 1;
  640. //printf("fc=%f df=%f dPass=%f dStop=%f d=%f alpha=%f A=%f D=%f N=%i\n",fcHz,dHz,dPass,dStop,d,alpha,A,D,N);
  641. // compute a kaiser function to truncate the sinc
  642. double wnd[ N ];
  643. cmVOD_Kaiser( wnd, N, alpha );
  644. // form an ideal FIR LP impulse response based on a sinc function
  645. cmFIRInitSinc(p,procSmpCnt,srate,N,fcHz,flags, wnd);
  646. //cmVOD_Print(stdout,1,p->coeffCnt,p->coeffV);
  647. return cmOkRC;
  648. }
  649. cmRC_t cmFIRInitSinc( cmFIR* p, unsigned procSmpCnt, double srate, unsigned sincSmpCnt, double fcHz, unsigned flags, const double* wndV )
  650. {
  651. cmRC_t rc;
  652. if((rc = cmFIRFinal(p)) != cmOkRC )
  653. return rc;
  654. p->coeffCnt = sincSmpCnt;
  655. p->outV = cmMemResizeZ( cmSample_t, p->outV, procSmpCnt );
  656. p->outN = procSmpCnt;
  657. p->coeffV = cmMemResizeZ( double, p->coeffV, p->coeffCnt );
  658. p->delayV = cmMemResizeZ( double, p->delayV, p->coeffCnt-1 ); // there is always one less delay than coeff
  659. p->delayIdx = 0;
  660. unsigned lp_flags = kNormalize_LPSincFl;
  661. lp_flags |= cmIsFlag(flags,kHighPassFIRFl) ? kHighPass_LPSincFl : 0;
  662. cmVOD_LP_Sinc(p->coeffV, p->coeffCnt, wndV, srate, fcHz, lp_flags );
  663. return cmOkRC;
  664. }
  665. cmRC_t cmFIRFinal( cmFIR* p )
  666. { return cmOkRC; }
  667. cmRC_t cmFIRExec( cmFIR* p, const cmSample_t* sbp, unsigned sn )
  668. {
  669. unsigned delayCnt = p->coeffCnt-1;
  670. int di = p->delayIdx;
  671. const cmSample_t* sep = sbp + sn;
  672. cmSample_t* op = p->outV;
  673. assert( di < delayCnt );
  674. assert( sn <= p->outN );
  675. // for each input sample
  676. while( sbp < sep )
  677. {
  678. // advance the delay line
  679. p->delayIdx = (p->delayIdx + 1) % delayCnt;
  680. const double* cbp = p->coeffV;
  681. const double* cep = cbp + p->coeffCnt;
  682. // mult input sample by coeff[0]
  683. double v = *sbp * *cbp++;
  684. // calc the output sample
  685. while( cbp<cep)
  686. {
  687. // note that the delay is being iterated bcmkwards
  688. if( di == -1 )
  689. di=delayCnt-1;
  690. v += *cbp++ * p->delayV[di];
  691. --di;
  692. }
  693. // store the output sample
  694. *op++ = v;
  695. // insert the input sample
  696. p->delayV[ p->delayIdx ] = *sbp++;
  697. // store the position of the newest ele in the delay line
  698. di = p->delayIdx;
  699. }
  700. return cmOkRC;
  701. }
  702. void cmFIRTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH )
  703. {
  704. unsigned N = 512;
  705. cmKbRecd kb;
  706. cmCtx c;
  707. cmCtxInit(&c,rpt,lhH,stH);
  708. double srate = N;
  709. unsigned procSmpCnt = N;
  710. cmPlotSetup("Test Proc Impl",2,1);
  711. cmSample_t in[ procSmpCnt ];
  712. cmVOS_Fill(in,procSmpCnt,0);
  713. in[0] = 1;
  714. cmVOS_Random(in,procSmpCnt, -1.0, 1.0 );
  715. cmFIR* ffp = cmFIRAllocKaiser( &c, NULL, procSmpCnt,srate, srate*0.025, srate/2, 10, 60, 0 );
  716. //cmFIR* ffp = cmFIRAllocSinc( &c, NULL, 32, 1000, 0 );
  717. cmFftSR* ftp = cmFftAllocSR( &c, NULL, ffp->outV, ffp->outN, kToPolarFftFl );
  718. cmFIRExec( ffp, in, procSmpCnt );
  719. cmFftExecSR( ftp, NULL, 0 );
  720. cmVOR_AmplitudeToDb(ftp->magV,ftp->binCnt,ftp->magV);
  721. printf("coeff cnt:%i\n",ffp->coeffCnt );
  722. cmPlotClear();
  723. cmPlotLineR( "test", NULL, ftp->magV, NULL, ftp->binCnt, NULL, kSolidPlotLineId );
  724. cmPlotDraw();
  725. cmKeyPress(&kb);
  726. cmFftFreeSR(&ftp);
  727. cmFIRFree(&ffp);
  728. }
  729. //------------------------------------------------------------------------------------------------------------
  730. cmFuncFilter* cmFuncFilterAlloc( cmCtx* c, cmFuncFilter* p, unsigned procSmpCnt, cmFuncFiltPtr_t funcPtr, void* userPtr, unsigned wndSmpCnt )
  731. {
  732. cmRC_t rc;
  733. cmFuncFilter* op = cmObjAlloc( cmFuncFilter,c, p );
  734. if( procSmpCnt > 0 && funcPtr != NULL && wndSmpCnt > 0 )
  735. {
  736. if( cmShiftBufAlloc(c,&p->shiftBuf,0,0,0) != NULL )
  737. if((rc = cmFuncFilterInit(op,procSmpCnt,funcPtr,userPtr,wndSmpCnt)) != cmOkRC )
  738. {
  739. cmShiftBuf* sbp = &p->shiftBuf;
  740. cmShiftBufFree(&sbp);
  741. cmObjFree(&op);
  742. }
  743. }
  744. return op;
  745. }
  746. cmRC_t cmFuncFilterFree( cmFuncFilter** pp )
  747. {
  748. cmRC_t rc = cmOkRC;
  749. if( pp!=NULL && *pp != NULL )
  750. {
  751. cmFuncFilter* p = *pp;
  752. if((rc = cmFuncFilterFinal(*pp)) == cmOkRC )
  753. {
  754. cmShiftBuf* sbp = &p->shiftBuf;
  755. cmShiftBufFree(&sbp);
  756. cmMemPtrFree(&p->outV);
  757. cmObjFree(pp);
  758. }
  759. }
  760. return rc;
  761. }
  762. cmRC_t cmFuncFilterInit( cmFuncFilter* p, unsigned procSmpCnt, cmFuncFiltPtr_t funcPtr, void* userPtr, unsigned wndSmpCnt )
  763. {
  764. cmRC_t rc;
  765. if(( rc = cmFuncFilterFinal(p)) != cmOkRC )
  766. return rc;
  767. // The shift buffer always consits of the p->wndSmpCnt-1 samples from the previous
  768. // exec followed by the latest procSmpCnt samples at the end of the buffer
  769. cmShiftBufInit( &p->shiftBuf, procSmpCnt, wndSmpCnt + procSmpCnt - 1, procSmpCnt );
  770. p->outV = cmMemResizeZ( cmSample_t, p->outV, procSmpCnt);
  771. p->outN = procSmpCnt;
  772. p->funcPtr = funcPtr;
  773. p->curWndSmpCnt = 1;
  774. p->wndSmpCnt = wndSmpCnt;
  775. return rc;
  776. }
  777. cmRC_t cmFuncFilterFinal( cmFuncFilter* p )
  778. { return cmOkRC; }
  779. cmRC_t cmFuncFilterExec( cmFuncFilter* p, const cmSample_t* sp, unsigned sn )
  780. {
  781. assert( sn <= p->outN);
  782. // The window used by this function is always causal. At the very beginning of the signal
  783. // the window length begins at 1 and increases until is has the length p->wndSmpCnt.
  784. // Note that this approach ignores any zeros automatically prepended to the beginning of the
  785. // signal by the shift buffer. The first window processed always has a length of 1 and
  786. // begins with the first actual sample given to the shift buffer. Successive windows increase
  787. // by one and start at the first actual sample until the full window length is available
  788. // from the shift buffer. At this point the window length remains constant and it is hopped
  789. // by one sample for each window.
  790. while(cmShiftBufExec(&p->shiftBuf,sp,sn))
  791. {
  792. const cmSample_t* fsp = p->shiftBuf.outV;
  793. cmSample_t* dp = p->outV;
  794. cmSample_t* ep = p->outV + sn; // produce as many output values as there are input samples
  795. // for each output sample
  796. while( dp < ep )
  797. {
  798. // the source range should never extend outside the shift buffer
  799. assert( fsp + p->curWndSmpCnt <= p->shiftBuf.outV + p->shiftBuf.wndSmpCnt );
  800. // calc the next output value
  801. *dp++ = p->funcPtr( fsp, p->curWndSmpCnt, p->userPtr );
  802. // if the window has not yet achieved its full length ...
  803. if( p->curWndSmpCnt < p->wndSmpCnt )
  804. ++p->curWndSmpCnt; // ... then increase its length by 1
  805. else
  806. ++fsp; // ... otherwise shift it ahead by 1
  807. }
  808. }
  809. return cmOkRC;
  810. }
  811. cmSample_t cmFuncFiltTestFunc( const cmSample_t* sp, unsigned sn, void* vp )
  812. {
  813. //printf("% f % f %p % i\n",*sp,*sp+(sn-1),sp,sn);
  814. cmSample_t v = cmVOS_Median(sp,sn);
  815. printf("%f ",v);
  816. return v;
  817. //return *sp;
  818. }
  819. void cmFuncFilterTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH )
  820. {
  821. unsigned procSmpCnt = 1;
  822. unsigned N = 32;
  823. cmSample_t v[N];
  824. cmCtx c;
  825. unsigned i;
  826. cmCtxAlloc(&c,rpt,lhH,stH);
  827. cmVOS_Seq(v,N,0,1);
  828. cmVOS_Print(rpt,1,32,v);
  829. cmFuncFilter* ffp = NULL;
  830. ffp = cmFuncFilterAlloc( &c, NULL, procSmpCnt, cmFuncFiltTestFunc, NULL, 5 );
  831. for(i=0; i<N; ++i)
  832. cmFuncFilterExec(ffp,v+(i*procSmpCnt),procSmpCnt);
  833. cmFuncFilterFree( &ffp );
  834. cmCtxFinal(&c);
  835. //unsigned v1n = 9;
  836. //cmSample_t v1[9] = { 1, 75, 91, 35, 6, 80, 40, 91, 79};
  837. //cmSample_t v1[10] = {53, 64, 48, 78, 30, 59, 7, 50, 71, 53 };
  838. //printf("Median: %f \n",cmVOS_Median(v1,v1+v1n));
  839. }
  840. //------------------------------------------------------------------------------------------------------------
  841. cmDhmm* cmDhmmAlloc( cmCtx* c, cmDhmm* ap, unsigned stateN, unsigned symN, cmReal_t* initV, cmReal_t* transM, cmReal_t* stsM )
  842. {
  843. cmDhmm* p = cmObjAlloc( cmDhmm, c, ap );
  844. if( stateN > 0 && symN > 0 )
  845. if( cmDhmmInit(p, stateN, symN, initV, transM, stsM ) != cmOkRC )
  846. cmObjFree(&p);
  847. return p;
  848. }
  849. cmRC_t cmDhmmFree( cmDhmm** pp )
  850. {
  851. cmRC_t rc = cmOkRC;
  852. cmDhmm* p = *pp;
  853. if( pp==NULL || *pp==NULL )
  854. return cmOkRC;
  855. if((rc = cmDhmmFinal(p)) != cmOkRC )
  856. return cmOkRC;
  857. cmObjFree(pp);
  858. return rc;
  859. }
  860. cmRC_t cmDhmmInit( cmDhmm* p, unsigned stateN, unsigned symN, cmReal_t* initV, cmReal_t* transM, cmReal_t* stsM )
  861. {
  862. cmRC_t rc;
  863. if((rc = cmDhmmFinal(p)) != cmOkRC )
  864. return rc;
  865. p->stateN = stateN;
  866. p->symN = symN;
  867. p->initV = initV;
  868. p->transM = transM;
  869. p->stsM = stsM;
  870. return cmOkRC;
  871. }
  872. cmRC_t cmDhmmFinal( cmDhmm* p )
  873. { return cmOkRC; }
  874. cmRC_t cmDhmmExec( cmDhmm* p )
  875. {
  876. return cmOkRC;
  877. }
  878. // Generate a random matrix with rows that sum to 1.0.
  879. void _cmDhmmGenRandMatrix( cmReal_t* dp, unsigned rn, unsigned cn )
  880. {
  881. cmReal_t v[ cn ];
  882. unsigned i,j;
  883. for(i=0; i<rn; ++i)
  884. {
  885. cmVOR_Random( v, cn, 0.0, 1.0 );
  886. cmVOR_NormalizeProbability( v, cn);
  887. for(j=0; j<cn; ++j)
  888. dp[ (j * rn) + i ] = v[j];
  889. }
  890. }
  891. enum { kEqualProbHmmFl=0x01, kRandProbHmmFl=0x02, kManualProbHmmFl=0x04 };
  892. void _cmDhmmGenProb( cmReal_t* dp, unsigned rn, unsigned cn, unsigned flags, const cmReal_t* sp )
  893. {
  894. switch( flags )
  895. {
  896. case kRandProbHmmFl:
  897. _cmDhmmGenRandMatrix( dp, rn, cn );
  898. break;
  899. case kEqualProbHmmFl:
  900. {
  901. // equal prob
  902. cmReal_t pr = 1.0/cn;
  903. unsigned i,j;
  904. for(i=0; i<rn; ++i)
  905. for(j=0; j<cn; ++j)
  906. dp[ (j*rn) + i ] = pr;
  907. }
  908. break;
  909. case kManualProbHmmFl:
  910. cmVOR_Copy( dp, (rn*cn), sp );
  911. break;
  912. default:
  913. assert(0);
  914. }
  915. }
  916. // generate a random integer in the range 0 to probN-1 where probV[ probN ] contains
  917. // the probability of generating each of the possible values.
  918. unsigned _cmDhmmGenRandInt( const cmReal_t* probV, unsigned probN, unsigned stride )
  919. {
  920. cmReal_t tmp[ probN ];
  921. cmReal_t cumSumV[ probN+1 ];
  922. const cmReal_t* sp = probV;
  923. cumSumV[0] = 0;
  924. if( stride > 1 )
  925. {
  926. cmVOR_CopyStride( tmp, probN, probV, stride );
  927. sp = tmp;
  928. }
  929. cmVOR_CumSum( cumSumV+1, probN, sp );
  930. return cmVOR_BinIndex( cumSumV, probN+1, (cmReal_t)rand()/RAND_MAX );
  931. }
  932. cmRC_t cmDhmmGenObsSequence( cmDhmm* p, unsigned* dbp, unsigned dn )
  933. {
  934. const unsigned* dep = dbp + dn;
  935. // generate the first state based on the init state prob. vector
  936. unsigned state = _cmDhmmGenRandInt( p->initV, p->stateN, 1 );
  937. // generate an observation from the state based on the symbol prob. vector
  938. *dbp++ = _cmDhmmGenRandInt( p->stsM + state, p->symN, p->stateN );
  939. while( dbp < dep )
  940. {
  941. // get the next state based on the previous state
  942. state = _cmDhmmGenRandInt( p->transM + state, p->stateN, p->stateN );
  943. // given a state generate an observation
  944. *dbp++ = _cmDhmmGenRandInt( p->stsM + state, p->symN, p->stateN );
  945. }
  946. return cmOkRC;
  947. }
  948. /// Perform a forward evaluation of the model given a set of observations.
  949. /// initPrV[ stateN ] is the probability of the model being in each state at the start of the evaluation.
  950. /// alphaM[ stateN, obsN ] is a return value and represents the probability of seeing each symbol at each time step.
  951. enum { kNoLogScaleHmmFl = 0x00, kLogScaleHmmFl = 0x01 };
  952. cmRC_t cmDHmmForwardEval( cmDhmm* p, const cmReal_t* initPrV, const unsigned* obsV, unsigned obsN, cmReal_t* alphaM, unsigned flags, cmReal_t* logProbPtr )
  953. {
  954. bool scaleFl = cmIsFlag(flags,kLogScaleHmmFl);
  955. cmReal_t logProb = 0;
  956. cmReal_t* abp = alphaM; // define first dest. column
  957. const cmReal_t* aep = abp + p->stateN;
  958. const cmReal_t* sts = p->stsM + (obsV[0] * p->stateN); // stsM[] column for assoc'd with first obs. symbol
  959. unsigned i;
  960. // calc the prob of begining in each state given the obs. symbol
  961. for(i=0; abp < aep; ++i )
  962. *abp++ = *initPrV++ * *sts++;
  963. // scale to prevent underflow
  964. if( scaleFl )
  965. {
  966. cmReal_t sum = cmVOR_Sum(abp-p->stateN,p->stateN);
  967. if( sum > 0 )
  968. {
  969. cmVOR_DivVS( abp-p->stateN,p->stateN,sum);
  970. logProb += log(sum);
  971. }
  972. }
  973. // for each time step
  974. for(i=1; i<obsN; ++i)
  975. {
  976. // next state 0 (first col, first row) is calc'd first
  977. const cmReal_t* tm = p->transM;
  978. // pick the stsM[] column assoc'd with ith observation symbol
  979. const cmReal_t* sts = p->stsM + (obsV[i] * p->stateN);
  980. // store a pointer to the alpha column assoc'd with obsV[i-1]
  981. const cmReal_t* app0 = abp - p->stateN;
  982. aep = abp + p->stateN;
  983. // for each dest state
  984. while( abp < aep )
  985. {
  986. // prob of being in each state on the previous time step
  987. const cmReal_t* app = app0;
  988. const cmReal_t* ape = app + p->stateN;
  989. *abp = 0;
  990. // for each src state - calc prob. of trans from src to dest
  991. while( app<ape )
  992. *abp += *app++ * *tm++;
  993. // calc prob of obs symbol in dest state
  994. *abp++ *= *sts++;
  995. }
  996. // scale to prevent underflow
  997. if( scaleFl )
  998. {
  999. cmReal_t sum = cmVOR_Sum(abp-p->stateN,p->stateN);
  1000. if( sum > 0 )
  1001. {
  1002. cmVOR_DivVS( abp-p->stateN,p->stateN,sum);
  1003. logProb += log(sum);
  1004. }
  1005. }
  1006. }
  1007. if( logProbPtr != NULL )
  1008. *logProbPtr = logProb;
  1009. return cmOkRC;
  1010. }
  1011. cmRC_t cmDHmmBcmkwardEval( cmDhmm* p, const unsigned* obsV, unsigned obsN, cmReal_t* betaM, unsigned flags )
  1012. {
  1013. bool scaleFl = cmIsFlag(flags,kLogScaleHmmFl);
  1014. int i,j,t;
  1015. cmVOR_Fill(betaM+((obsN-1)*p->stateN),p->stateN,1.0);
  1016. // for each time step
  1017. for(t=obsN-2; t>=0; --t)
  1018. {
  1019. // for each state at t
  1020. for(i=0; i<p->stateN; ++i)
  1021. {
  1022. double Bt = 0;
  1023. // for each state at t+1
  1024. for(j=0; j<p->stateN; ++j)
  1025. {
  1026. double aij = p->transM[ (j * p->stateN) + i ];
  1027. double bj = p->stsM[ (obsV[t+1] * p->stateN) + j ];
  1028. double Bt1 = betaM[ ((t+1) * p->stateN) + j ];
  1029. Bt += aij * bj * Bt1;
  1030. }
  1031. betaM[ (t * p->stateN) + i ] = Bt;
  1032. }
  1033. if( scaleFl )
  1034. {
  1035. double* bp = betaM + (t * p->stateN);
  1036. double sum = cmVOR_Sum(bp, p->stateN );
  1037. if( sum > 0 )
  1038. cmVOR_DivVS( bp, p->stateN, sum );
  1039. }
  1040. }
  1041. return cmOkRC;
  1042. }
  1043. void _cmDhmmNormRow( cmReal_t* p, unsigned pn, unsigned stride, const cmReal_t* sp )
  1044. {
  1045. if( sp == NULL )
  1046. sp = p;
  1047. cmReal_t sum = 0;
  1048. unsigned n = pn * stride;
  1049. const cmReal_t* bp = sp;
  1050. const cmReal_t* ep = bp + n;
  1051. for(; bp<ep; bp+=stride)
  1052. sum += *bp;
  1053. for(ep = p+n; p<ep; p+=stride,sp+=stride)
  1054. *p = *sp / sum;
  1055. }
  1056. void _cmDhmmNormMtxRows( cmReal_t* dp, unsigned rn, unsigned cn, const cmReal_t* sp )
  1057. {
  1058. const cmReal_t* erp = sp + rn;
  1059. while( sp < erp )
  1060. _cmDhmmNormRow( dp++, cn, rn, sp++ );
  1061. }
  1062. cmRC_t cmDhmmTrainEM( cmDhmm* p, const unsigned* obsV, unsigned obsN, unsigned iterCnt, unsigned flags )
  1063. {
  1064. unsigned i,j,k,t;
  1065. cmReal_t alphaM[ p->stateN * obsN ];
  1066. cmReal_t betaM[ p->stateN * obsN ];
  1067. cmReal_t g[ p->stateN * obsN ];
  1068. cmReal_t q[ p->stateN * p->symN ];
  1069. cmReal_t E[ p->stateN * p->stateN ];
  1070. cmReal_t logProb = 0;
  1071. //cmDhmmReport(p->obj.ctx,p);
  1072. for(k=0; k<iterCnt; ++k)
  1073. {
  1074. cmVOR_Fill( q, (p->stateN * p->symN), 0 );
  1075. cmVOR_Fill( E, (p->stateN * p->stateN), 0 );
  1076. // calculate alpha and beta
  1077. cmDHmmForwardEval( p, p->initV, obsV, obsN, alphaM, flags, &logProb);
  1078. cmDHmmBcmkwardEval( p, obsV, obsN, betaM, flags );
  1079. // gamma[ stateN, obsN ] = alphaM .* betaM - gamma is the probability of being in each state at each time step
  1080. cmVOR_MultVVV( g,(p->stateN*obsN), alphaM, betaM );
  1081. // normalize gamma
  1082. for(i=0; i<obsN; ++i)
  1083. cmVOR_NormalizeProbability( g + (i*p->stateN), p->stateN );
  1084. //printf("ITER:%i logProb:%f\n",k,logProb);
  1085. // count the number of times state i emits obsV[0] in the starting location
  1086. cmVOR_Copy( q + (obsV[0] * p->stateN), p->stateN, g );
  1087. for(t=0; t<obsN-1; ++t)
  1088. {
  1089. // point to alpha[:,t] and beta[:,t+1]
  1090. const cmReal_t* alpha_t0 = alphaM + (t*p->stateN);
  1091. const cmReal_t* beta_t1 = betaM + ((t+1)*p->stateN);
  1092. cmReal_t Et[ p->stateN * p->stateN ];
  1093. cmReal_t Esum = 0;
  1094. // for each source state
  1095. for(i=0; i<p->stateN; ++i)
  1096. {
  1097. // for each dest state
  1098. for(j=0; j<p->stateN; ++j)
  1099. {
  1100. // prob of transitioning from state i to j and emitting obs[t] at time t
  1101. cmReal_t Eps = alpha_t0[i] * p->transM[ (j*p->stateN) + i ] * p->stsM[ (obsV[t+1]*p->stateN) + j ] * beta_t1[j];
  1102. // count the number of transitions from i to j
  1103. Et[ (j*p->stateN) + i ] = Eps;
  1104. Esum += Eps;
  1105. }
  1106. // count the number of times state i emits obsV[t]
  1107. q[ (obsV[t+1] * p->stateN) + i ] += g[ ((t+1)*p->stateN) + i ];
  1108. }
  1109. // normalize Et and sum it into E
  1110. cmVOR_DivVS( Et, (p->stateN*p->stateN), Esum );
  1111. cmVOR_AddVV( E, (p->stateN*p->stateN), Et );
  1112. }
  1113. // update the model
  1114. _cmDhmmNormMtxRows( p->initV, 1, p->stateN, g );
  1115. _cmDhmmNormMtxRows( p->transM, p->stateN, p->stateN, E );
  1116. _cmDhmmNormMtxRows( p->stsM, p->stateN, p->symN, q );
  1117. }
  1118. return cmOkRC;
  1119. }
  1120. cmRC_t cmDhmmReport( cmDhmm* p )
  1121. {
  1122. cmVOR_PrintL("initV:\n", p->obj.err.rpt, 1, p->stateN, p->initV );
  1123. cmVOR_PrintL("transM:\n", p->obj.err.rpt, p->stateN, p->stateN, p->transM );
  1124. cmVOR_PrintL("symM:\n", p->obj.err.rpt, p->stateN, p->symN, p->stsM );
  1125. return cmOkRC;
  1126. }
  1127. void cmDhmmTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH )
  1128. {
  1129. unsigned stateN = 2;
  1130. unsigned symN = 3;
  1131. unsigned obsN = 4;
  1132. unsigned iterN = 10;
  1133. cmReal_t initV0[ stateN ];
  1134. cmReal_t transM0[ stateN * stateN ];
  1135. cmReal_t stsM0[ symN * stateN ];
  1136. cmReal_t initV1[ stateN ];
  1137. cmReal_t transM1[ stateN * stateN ];
  1138. cmReal_t stsM1[ symN * stateN ];
  1139. unsigned obsV[ obsN ];
  1140. unsigned hist[ symN ];
  1141. unsigned genFl = kManualProbHmmFl;
  1142. cmReal_t initV[] =
  1143. {
  1144. 0.44094,
  1145. 0.55906
  1146. };
  1147. cmReal_t transM[] =
  1148. {
  1149. 0.48336,
  1150. 0.81353,
  1151. 0.51664,
  1152. 0.18647,
  1153. };
  1154. cmReal_t stsM[] =
  1155. {
  1156. 0.20784,
  1157. 0.18698,
  1158. 0.43437,
  1159. 0.24102,
  1160. 0.35779,
  1161. 0.57199
  1162. };
  1163. unsigned obsM[] = { 2, 2, 2, 0 };
  1164. cmReal_t initV2[] = { 0.79060, 0.20940 };
  1165. cmReal_t transM2[] = { 0.508841, 0.011438, 0.491159, 0.988562 };
  1166. cmReal_t stsM2[] = { 0.25789, 0.35825, 0.61981, 0.42207, 0.12230, 0.21969 };
  1167. //srand( time(NULL) );
  1168. // generate a random HMM
  1169. _cmDhmmGenProb( initV0, 1, stateN, genFl, initV );
  1170. _cmDhmmGenProb( transM0, stateN, stateN, genFl, transM );
  1171. _cmDhmmGenProb( stsM0, stateN, symN, genFl, stsM );
  1172. cmCtx* c = cmCtxAlloc( NULL, rpt, lhH, stH);
  1173. cmDhmm* h0p = cmDhmmAlloc( c, NULL, stateN, symN, initV0, transM0, stsM0 );
  1174. // generate an observation sequence based on the random HMM
  1175. //cmDhmmGenObsSequence(c, h0p, obsV, obsN );
  1176. memcpy(obsV,obsM,obsN*sizeof(unsigned));
  1177. if( 0 )
  1178. {
  1179. // print the HMM
  1180. cmDhmmReport( h0p);
  1181. // print the observation symbols
  1182. cmVOU_PrintL("obs:\n", rpt, 1, obsN, obsV );
  1183. // print the histogram of the obs. symbols
  1184. cmVOU_Hist( hist, symN, obsV, obsN );
  1185. cmVOU_PrintL("hist:\n", rpt, 1, symN, hist );
  1186. // calc alpha (the forward probabilities)
  1187. cmReal_t alphaM[ h0p->stateN*obsN ];
  1188. cmReal_t logProb=0;
  1189. cmDHmmForwardEval( h0p, h0p->initV, obsV, obsN, alphaM, kLogScaleHmmFl, &logProb);
  1190. printf("log prob:%f\n alpha:\n", logProb );
  1191. cmVOR_Print( rpt, h0p->stateN, obsN, alphaM );
  1192. // calc beta (the bcmkward probabilities)
  1193. cmReal_t betaM[ h0p->stateN*obsN ];
  1194. logProb=0;
  1195. cmDHmmBcmkwardEval( h0p, obsV, obsN, betaM, kLogScaleHmmFl);
  1196. printf("log prob:%f\n beta:\n", logProb );
  1197. cmVOR_Print( h0p->obj.err.rpt, h0p->stateN, obsN, betaM );
  1198. }
  1199. // initialize a second HMM with random probabilities
  1200. _cmDhmmGenProb( initV1, 1, stateN, kManualProbHmmFl, initV2 );
  1201. _cmDhmmGenProb( transM1, stateN, stateN, kManualProbHmmFl, transM2 );
  1202. _cmDhmmGenProb( stsM1, stateN, symN, kManualProbHmmFl, stsM2 );
  1203. cmDhmm* h1p = cmDhmmAlloc( c, NULL, stateN, symN, initV1, transM1, stsM1 );
  1204. cmDhmmTrainEM( h1p, obsV, obsN, iterN, kLogScaleHmmFl );
  1205. cmDhmmFree(&h1p);
  1206. cmDhmmFree(&h0p);
  1207. cmCtxFree(&c);
  1208. }
  1209. //------------------------------------------------------------------------------------------------------------
  1210. cmConvolve* cmConvolveAlloc( cmCtx* c, cmConvolve* ap, const cmSample_t* h, unsigned hn, unsigned procSmpCnt )
  1211. {
  1212. cmConvolve* p = cmObjAlloc( cmConvolve, c, ap);
  1213. p->fft = cmFftAllocSR( c,NULL,NULL,0,kNoConvertFftFl);
  1214. p->ifft= cmIFftAllocRS(c,NULL,p->fft->binCnt);
  1215. if( hn > 0 && procSmpCnt > 0 )
  1216. if( cmConvolveInit(p,h,hn,procSmpCnt) != cmOkRC )
  1217. cmObjFree(&p);
  1218. return p;
  1219. }
  1220. cmRC_t cmConvolveFree( cmConvolve** pp )
  1221. {
  1222. cmRC_t rc;
  1223. cmConvolve* p = *pp;
  1224. if( pp == NULL || *pp == NULL )
  1225. return cmOkRC;
  1226. if((rc = cmConvolveFinal(p)) != cmOkRC )
  1227. return cmOkRC;
  1228. cmFftFreeSR(&p->fft);
  1229. cmIFftFreeRS(&p->ifft);
  1230. cmMemPtrFree(&p->H);
  1231. cmMemPtrFree(&p->outV);
  1232. cmObjFree(pp);
  1233. return cmOkRC;
  1234. }
  1235. cmRC_t cmConvolveInit( cmConvolve* p, const cmSample_t* h, unsigned hn, unsigned procSmpCnt )
  1236. {
  1237. cmRC_t rc;
  1238. unsigned i;
  1239. unsigned cn = cmNextPowerOfTwo( hn + procSmpCnt - 1 );
  1240. if((rc = cmConvolveFinal(p)) != cmOkRC )
  1241. return rc;
  1242. cmFftInitSR( p->fft, NULL, cn, kNoConvertFftFl );
  1243. cmIFftInitRS( p->ifft, p->fft->binCnt);
  1244. p->H = cmMemResizeZ( cmComplexR_t,p->H, p->fft->binCnt );
  1245. p->outV = cmMemResizeZ( cmSample_t,p->outV, cn );
  1246. p->olaV = p->outV + procSmpCnt;
  1247. p->outN = procSmpCnt;
  1248. p->hn = hn;
  1249. // take the FFT of the impulse response
  1250. cmFftExecSR( p->fft, h, hn );
  1251. // copy the FFT of the impulse response to p->H[]
  1252. for(i=0; i<p->fft->binCnt; ++i)
  1253. p->H[i] = p->fft->complexV[i] / p->fft->wndSmpCnt;
  1254. return cmOkRC;
  1255. }
  1256. cmRC_t cmConvolveFinal( cmConvolve* p )
  1257. { return cmOkRC; }
  1258. cmRC_t cmConvolveExec( cmConvolve* p, const cmSample_t* x, unsigned xn )
  1259. {
  1260. unsigned i;
  1261. // take FT of input signal
  1262. cmFftExecSR( p->fft, x, xn );
  1263. // multiply the signal spectra of the input signal and impulse response
  1264. for(i=0; i<p->fft->binCnt; ++i)
  1265. p->ifft->complexV[i] = p->H[i] * p->fft->complexV[i];
  1266. // take the IFFT of the convolved spectrum
  1267. cmIFftExecRS(p->ifft,NULL);
  1268. // sum with previous impulse response tail
  1269. cmVOS_AddVVV( p->outV, p->outN-1, p->olaV, p->ifft->outV );
  1270. // first sample of the impulse response tail is complete
  1271. p->outV[p->outN-1] = p->ifft->outV[p->outN-1];
  1272. // store the new impulse response tail
  1273. cmVOS_Copy(p->olaV,p->hn-1,p->ifft->outV + p->outN );
  1274. return cmOkRC;
  1275. }
  1276. cmRC_t cmConvolveSignal( cmCtx* c, const cmSample_t* h, unsigned hn, const cmSample_t* x, unsigned xn, cmSample_t* y, unsigned yn )
  1277. {
  1278. cmConvolve* p = cmConvolveAlloc(c,NULL,h,hn,xn);
  1279. cmConvolveExec(p,x,xn);
  1280. unsigned n = cmMin(p->outN,yn);
  1281. cmVOS_Copy(y,n,p->outV);
  1282. if( yn > p->outN )
  1283. {
  1284. unsigned m = cmMin(yn-p->outN,p->hn-1);
  1285. cmVOS_Copy(y+n,m,p->olaV);
  1286. }
  1287. cmConvolveFree(&p);
  1288. return cmOkRC;
  1289. }
  1290. cmRC_t cmConvolveTest(cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH )
  1291. {
  1292. cmCtx *c = cmCtxAlloc(NULL,rpt,lhH,stH);
  1293. cmSample_t h[] = { 1, .5, .25, 0, 0 };
  1294. unsigned hn = sizeof(h) / sizeof(h[0]);
  1295. cmSample_t x[] = { 1, 0, 0, 0, 1, 0, 0, 0 };
  1296. unsigned xn = sizeof(x) / sizeof(x[0]);
  1297. unsigned yn = xn+hn-1;
  1298. cmSample_t y[yn];
  1299. //cmVOS_Hann(h,5);
  1300. cmConvolve* p = cmConvolveAlloc(c,NULL,h,hn,xn);
  1301. cmConvolveExec(p,x,xn);
  1302. cmVOS_Print( rpt, 1, p->outN, p->outV );
  1303. cmVOS_Print( rpt, 1, p->hn-1, p->olaV );
  1304. cmConvolveFree(&p);
  1305. cmConvolveSignal(c,h,hn,x,xn,y,yn);
  1306. cmVOS_Print( rpt, 1, hn+xn-1, y );
  1307. cmCtxFree(&c);
  1308. return cmOkRC;
  1309. }
  1310. //------------------------------------------------------------------------------------------------------------
  1311. cmBfcc* cmBfccAlloc( cmCtx* ctx, cmBfcc* ap, unsigned bandCnt, unsigned binCnt, double binHz )
  1312. {
  1313. cmBfcc* p = cmObjAlloc( cmBfcc, ctx, ap );
  1314. if( bandCnt > 0 )
  1315. if( cmBfccInit( p, bandCnt, binCnt, binHz ) != cmOkRC )
  1316. cmBfccFree(&p);
  1317. return p;
  1318. }
  1319. cmRC_t cmBfccFree( cmBfcc** pp )
  1320. {
  1321. cmRC_t rc;
  1322. if( pp== NULL || *pp==NULL)
  1323. return cmOkRC;
  1324. cmBfcc* p = *pp;
  1325. if((rc = cmBfccFinal(p)) != cmOkRC )
  1326. return rc;
  1327. cmMemPtrFree(&p->dctMtx);
  1328. cmMemPtrFree(&p->filtMask);
  1329. cmMemPtrFree(&p->outV);
  1330. cmObjFree(pp);
  1331. return rc;
  1332. }
  1333. cmRC_t cmBfccInit( cmBfcc* p, unsigned bandCnt, unsigned binCnt, double binHz )
  1334. {
  1335. cmRC_t rc;
  1336. if((rc = cmBfccFinal(p)) != cmOkRC )
  1337. return rc;
  1338. p->dctMtx = cmMemResizeZ( cmReal_t, p->dctMtx, bandCnt*bandCnt);
  1339. p->filtMask = cmMemResizeZ( cmReal_t, p->filtMask, bandCnt*binCnt);
  1340. p->outV = cmMemResizeZ( cmReal_t, p->outV, bandCnt );
  1341. p->binCnt = binCnt;
  1342. p->bandCnt = bandCnt;
  1343. cmVOR_BarkMask( p->filtMask, bandCnt, binCnt, binHz );
  1344. cmVOR_DctMatrix(p->dctMtx, bandCnt, bandCnt );
  1345. return rc;
  1346. }
  1347. cmRC_t cmBfccFinal( cmBfcc* p )
  1348. { return cmOkRC; }
  1349. cmRC_t cmBfccExec( cmBfcc* p, const cmReal_t* magV, unsigned binCnt )
  1350. {
  1351. assert( binCnt <= p->binCnt );
  1352. cmReal_t t[ p->bandCnt ];
  1353. cmReal_t v[ binCnt ];
  1354. // convert magnitude to power
  1355. cmVOR_PowVVS(v,binCnt,magV,2.0);
  1356. // apply the filter mask to the power spectrum
  1357. cmVOR_MultVMV( t, p->bandCnt, p->filtMask, binCnt, v );
  1358. //cmVOR_PrintL("\t:\n", p->obj.ctx->outFuncPtr, 1, p->bandCnt, t);
  1359. cmVOR_ReplaceLte( t, p->bandCnt, t, 0, 0.1e-5 );
  1360. cmVOR_LogV( t, p->bandCnt, t );
  1361. // decorellate the bands with a DCT
  1362. cmVOR_MultVMV( p->outV, p->bandCnt, p->dctMtx, p->bandCnt, t );
  1363. return cmOkRC;
  1364. }
  1365. void cmBfccTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH )
  1366. {
  1367. double srate = 11025;
  1368. unsigned binCnt = 129;
  1369. double binHz = srate/(binCnt-1);
  1370. unsigned bandCnt = kDefaultBarkBandCnt;
  1371. cmCtx* c = cmCtxAlloc( NULL, rpt, lhH, stH );
  1372. cmBfcc* b = cmBfccAlloc( c, NULL, bandCnt, binCnt, binHz );
  1373. cmReal_t powV[] = {
  1374. 0.8402, 0.3944, 0.7831, 0.7984, 0.9116, 0.1976, 0.3352, 0.7682, 0.2778, 0.5540,
  1375. 0.4774, 0.6289, 0.3648, 0.5134, 0.9522, 0.9162, 0.6357, 0.7173, 0.1416, 0.6070,
  1376. 0.0163, 0.2429, 0.1372, 0.8042, 0.1567, 0.4009, 0.1298, 0.1088, 0.9989, 0.2183,
  1377. 0.5129, 0.8391, 0.6126, 0.2960, 0.6376, 0.5243, 0.4936, 0.9728, 0.2925, 0.7714,
  1378. 0.5267, 0.7699, 0.4002, 0.8915, 0.2833, 0.3525, 0.8077, 0.9190, 0.0698, 0.9493,
  1379. 0.5260, 0.0861, 0.1922, 0.6632, 0.8902, 0.3489, 0.0642, 0.0200, 0.4577, 0.0631,
  1380. 0.2383, 0.9706, 0.9022, 0.8509, 0.2667, 0.5398, 0.3752, 0.7602, 0.5125, 0.6677,
  1381. 0.5316, 0.0393, 0.4376, 0.9318, 0.9308, 0.7210, 0.2843, 0.7385, 0.6400, 0.3540,
  1382. 0.6879, 0.1660, 0.4401, 0.8801, 0.8292, 0.3303, 0.2290, 0.8934, 0.3504, 0.6867,
  1383. 0.9565, 0.5886, 0.6573, 0.8587, 0.4396, 0.9240, 0.3984, 0.8148, 0.6842, 0.9110,
  1384. 0.4825, 0.2158, 0.9503, 0.9201, 0.1477, 0.8811, 0.6411, 0.4320, 0.6196, 0.2811,
  1385. 0.7860, 0.3075, 0.4470, 0.2261, 0.1875, 0.2762, 0.5564, 0.4165, 0.1696, 0.9068,
  1386. 0.1032, 0.1261, 0.4954, 0.7605, 0.9848, 0.9350, 0.6844, 0.3832, 0.7498 };
  1387. //cmVOR_Random(powV, binCnt, 0.0, 1.0 );
  1388. cmBfccExec(b,powV,binCnt);
  1389. //cmVOR_PrintL("\nin:\n", rpt, 1, binCnt, powV);
  1390. //cmVOR_PrintL("\nfilt:\n", rpt, bandCnt, binCnt, b->filtMask);
  1391. //cmVOR_PrintL("\ndct:\n", rpt, bandCnt, bandCnt,b->dctMtx);
  1392. cmVOR_PrintL("\nbfcc:\n", rpt, 1, bandCnt, b->outV);
  1393. cmBfccFree(&b);
  1394. cmCtxFree(&c);
  1395. }
  1396. //------------------------------------------------------------------------------------------------------------
  1397. cmCeps* cmCepsAlloc( cmCtx* ctx, cmCeps* ap, unsigned binCnt, unsigned outN )
  1398. {
  1399. cmCeps* p = cmObjAlloc( cmCeps, ctx, ap );
  1400. //cmIFftAllocRR( ctx, &p->ft, 0 );
  1401. if( binCnt > 0 )
  1402. if( cmCepsInit( p, binCnt, outN ) != cmOkRC )
  1403. cmCepsFree(&p);
  1404. return p;
  1405. }
  1406. cmRC_t cmCepsFree( cmCeps** pp )
  1407. {
  1408. cmRC_t rc;
  1409. if( pp== NULL || *pp==NULL)
  1410. return cmOkRC;
  1411. cmCeps* p = *pp;
  1412. if((rc = cmCepsFinal(p)) != cmOkRC )
  1413. return rc;
  1414. //cmObjFreeStatic( cmIFftFreeRR, cmIFftRR, p->ft );
  1415. cmMemPtrFree(&p->dctM);
  1416. cmMemPtrFree(&p->outV);
  1417. cmObjFree(pp);
  1418. return rc;
  1419. }
  1420. cmRC_t cmCepsInit( cmCeps* p, unsigned binCnt, unsigned outN )
  1421. {
  1422. cmRC_t rc;
  1423. if((rc = cmCepsFinal(p)) != cmOkRC )
  1424. return rc;
  1425. //cmIFftInitRR( &p->ft, binCnt );
  1426. p->dct_cn = (binCnt-1)*2;
  1427. p->dctM = cmMemResize( cmReal_t, p->dctM, outN*p->dct_cn );
  1428. p->outN = outN; //p->ft.outN;
  1429. p->outV = cmMemResizeZ( cmReal_t, p->outV, outN ); //p->ft.outV;
  1430. p->binCnt = binCnt;
  1431. assert( outN <= p->dct_cn );
  1432. cmVOR_DctMatrix( p->dctM, outN, p->dct_cn );
  1433. return rc;
  1434. }
  1435. cmRC_t cmCepsFinal( cmCeps* p )
  1436. { return cmOkRC; }
  1437. cmRC_t cmCepsExec( cmCeps* p, const cmReal_t* magV, const cmReal_t* phsV, unsigned binCnt )
  1438. {
  1439. assert( binCnt == p->binCnt );
  1440. cmReal_t v[ p->dct_cn ];
  1441. // guard against zeros in the magn spectrum
  1442. cmVOR_ReplaceLte(v,binCnt,magV,0.0,0.00001);
  1443. // take the log of the spectrum
  1444. cmVOR_LogV(v,binCnt,v);
  1445. // reconstruct the negative frequencies
  1446. int i,j;
  1447. for(i=1,j=p->dct_cn-1; i<binCnt; ++i,--j)
  1448. v[j] = v[i];
  1449. // take the DCT
  1450. cmVOR_MultVMV( p->outV, p->outN, p->dctM, p->dct_cn, v );
  1451. //cmIFftExecPolarRR( &p->ft, v, phsV );
  1452. return cmOkRC;
  1453. }
  1454. //------------------------------------------------------------------------------------------------------------
  1455. cmOla* cmOlaAlloc( cmCtx* ctx, cmOla* ap, unsigned wndSmpCnt, unsigned hopSmpCnt, unsigned procSmpCnt, unsigned wndTypeId )
  1456. {
  1457. cmOla* p = cmObjAlloc( cmOla, ctx, ap );
  1458. cmWndFuncAlloc( ctx, &p->wf, kHannWndId, wndSmpCnt, 0);
  1459. if( wndSmpCnt > 0 )
  1460. if( cmOlaInit(p,wndSmpCnt,hopSmpCnt,procSmpCnt,wndTypeId) != cmOkRC )
  1461. cmOlaFree(&p);
  1462. return p;
  1463. }
  1464. cmRC_t cmOlaFree( cmOla** pp )
  1465. {
  1466. cmRC_t rc;
  1467. if( pp==NULL || *pp==NULL )
  1468. return cmOkRC;
  1469. cmOla* p = *pp;
  1470. if(( rc = cmOlaFinal(p)) != cmOkRC )
  1471. return rc;
  1472. cmMemPtrFree(&p->bufV);
  1473. cmMemPtrFree(&p->outV);
  1474. cmObjFreeStatic( cmWndFuncFree, cmWndFunc, p->wf );
  1475. cmObjFree(pp);
  1476. return rc;
  1477. }
  1478. cmRC_t cmOlaInit( cmOla* p, unsigned wndSmpCnt, unsigned hopSmpCnt, unsigned procSmpCnt, unsigned wndTypeId )
  1479. {
  1480. cmRC_t rc;
  1481. if((rc = cmOlaFinal(p)) != cmOkRC )
  1482. return rc;
  1483. if((rc = cmWndFuncInit( &p->wf, wndTypeId, wndSmpCnt, 0)) != cmOkRC )
  1484. return rc;
  1485. p->bufV = cmMemResizeZ( cmSample_t, p->bufV, wndSmpCnt );
  1486. p->outV = cmMemResizeZ( cmSample_t, p->outV, hopSmpCnt );
  1487. p->outPtr = p->outV + hopSmpCnt;
  1488. // hopSmpCnt must be an even multiple of procSmpCnt
  1489. assert( hopSmpCnt % procSmpCnt == 0 );
  1490. assert( wndSmpCnt >= hopSmpCnt );
  1491. p->wndSmpCnt = wndSmpCnt;
  1492. p->hopSmpCnt = hopSmpCnt;
  1493. p->procSmpCnt= procSmpCnt;
  1494. p->idx = 0;
  1495. return rc;
  1496. }
  1497. cmRC_t cmOlaFinal( cmOla* p )
  1498. { return cmOkRC; }
  1499. // The incoming buffer and the ola buf (bufV)
  1500. // can be divided into three logical parts:
  1501. //
  1502. // [head][middle][tail]
  1503. //
  1504. // head = hopSmpCnt values
  1505. // tail = hopSmpCnt values
  1506. // middle = wndSmpCnt - (2*hopSmpCnt) values
  1507. //
  1508. // Each exec can be broken into three phases:
  1509. //
  1510. // outV = bufV[tail] + in[head]
  1511. // bufV[middle] += in[middle]
  1512. // bufV[tail] = in[tail]
  1513. //
  1514. cmRC_t cmOlaExecS( cmOla* p, const cmSample_t* sp, unsigned sN )
  1515. {
  1516. assert( sN == p->wndSmpCnt );
  1517. cmRC_t rc = cmOkRC;
  1518. const cmSample_t* ep = sp + sN;
  1519. const cmSample_t* wp = p->wf.wndV;
  1520. int i,j,k,n;
  1521. // [Sum head of incoming samples with tail of ola buf]
  1522. // fill outV with the bufV[idx:idx+hopSmpCnt] + sp[hopSmpCnt]
  1523. for(i=0; i<p->hopSmpCnt; ++i)
  1524. {
  1525. p->outV[i] = p->bufV[p->idx++] + (*sp++ * *wp++);
  1526. if( p->idx == p->wndSmpCnt )
  1527. p->idx = 0;
  1528. }
  1529. // [Sum middle of incoming samples with middle of ola buf]
  1530. // sum next wndSmpCnt - hopSmpCnt samples of sp[] into bufV[]
  1531. n = p->wndSmpCnt - (2*p->hopSmpCnt);
  1532. k = p->idx;
  1533. for(j=0; j<n; ++j)
  1534. {
  1535. p->bufV[k++] += (*sp++ * *wp++);
  1536. if( k == p->wndSmpCnt )
  1537. k = 0;
  1538. }
  1539. // [Assign tail of incoming to tail of ola buf]
  1540. // assign ending samples from sp[] into bufV[]
  1541. while( sp < ep )
  1542. {
  1543. p->bufV[k++] = (*sp++ * *wp++);
  1544. if( k == p->wndSmpCnt )
  1545. k = 0;
  1546. }
  1547. p->outPtr = p->outV;
  1548. return rc;
  1549. }
  1550. cmRC_t cmOlaExecR( cmOla* p, const cmReal_t* sp, unsigned sN )
  1551. {
  1552. assert( sN == p->wndSmpCnt );
  1553. cmRC_t rc = cmOkRC;
  1554. const cmReal_t* ep = sp + sN;
  1555. const cmSample_t* wp = p->wf.wndV;
  1556. int i,j,k,n;
  1557. // fill outV with the bufV[idx:idx+hopSmpCnt] + sp[hopSmpCnt]
  1558. for(i=0; i<p->hopSmpCnt; ++i)
  1559. {
  1560. p->outV[i] = p->bufV[p->idx++] + (*sp++ * *wp++);
  1561. if( p->idx == p->wndSmpCnt )
  1562. p->idx = 0;
  1563. }
  1564. // sum next wndSmpCnt - hopSmpCnt samples of sp[] into bufV[]
  1565. n = p->wndSmpCnt - (2*p->hopSmpCnt);
  1566. k = p->idx;
  1567. for(j=0; j<n; ++j)
  1568. {
  1569. p->bufV[k++] += (*sp++ * *wp++);
  1570. if( k == p->wndSmpCnt )
  1571. k = 0;
  1572. }
  1573. // assign ending samples from sp[] into bufV[]
  1574. while( sp < ep )
  1575. {
  1576. p->bufV[k++] = (*sp++ * *wp++);
  1577. if( k == p->wndSmpCnt )
  1578. k = 0;
  1579. }
  1580. p->outPtr = p->outV;
  1581. return rc;
  1582. }
  1583. const cmSample_t* cmOlaExecOut(cmOla* p)
  1584. {
  1585. const cmSample_t* sp = p->outPtr;
  1586. if( sp >= p->outV + p->hopSmpCnt )
  1587. return NULL;
  1588. p->outPtr += p->procSmpCnt;
  1589. return sp;
  1590. }
  1591. //------------------------------------------------------------------------------------------------------------
  1592. cmPhsToFrq* cmPhsToFrqAlloc( cmCtx* c, cmPhsToFrq* ap, double srate, unsigned binCnt, unsigned hopSmpCnt )
  1593. {
  1594. cmPhsToFrq* p = cmObjAlloc( cmPhsToFrq, c, ap );
  1595. if( srate != 0 )
  1596. if( cmPhsToFrqInit( p, srate, binCnt, hopSmpCnt ) != cmOkRC )
  1597. cmPhsToFrqFree(&p);
  1598. return p;
  1599. }
  1600. cmRC_t cmPhsToFrqFree( cmPhsToFrq** pp )
  1601. {
  1602. cmRC_t rc = cmOkRC;
  1603. cmPhsToFrq* p = *pp;
  1604. if( pp==NULL || *pp== NULL )
  1605. return rc;
  1606. if((rc = cmPhsToFrqFinal(p)) != cmOkRC )
  1607. return rc;
  1608. cmMemPtrFree(&p->hzV);
  1609. cmMemPtrFree(&p->phsV);
  1610. cmMemPtrFree(&p->wV);
  1611. cmObjFree(pp);
  1612. return rc;
  1613. }
  1614. cmRC_t cmPhsToFrqInit( cmPhsToFrq* p, double srate, unsigned binCnt, unsigned hopSmpCnt )
  1615. {
  1616. cmRC_t rc;
  1617. unsigned i;
  1618. if((rc = cmPhsToFrqFinal(p)) != cmOkRC )
  1619. return rc;
  1620. p->hzV = cmMemResizeZ( cmReal_t, p->hzV, binCnt );
  1621. p->phsV = cmMemResizeZ( cmReal_t, p->phsV, binCnt );
  1622. p->wV = cmMemResizeZ( cmReal_t, p->wV, binCnt );
  1623. p->srate = srate;
  1624. p->binCnt = binCnt;
  1625. p->hopSmpCnt = hopSmpCnt;
  1626. for(i=0; i<binCnt; ++i)
  1627. p->wV[i] = M_PI * i * hopSmpCnt / (binCnt-1);
  1628. return rc;
  1629. }
  1630. cmRC_t cmPhsToFrqFinal(cmPhsToFrq* p )
  1631. { return cmOkRC; }
  1632. cmRC_t cmPhsToFrqExec( cmPhsToFrq* p, const cmReal_t* phsV )
  1633. {
  1634. cmRC_t rc = cmOkRC;
  1635. unsigned i;
  1636. double twoPi = 2.0 * M_PI;
  1637. double den = twoPi * p->hopSmpCnt;
  1638. for(i=0; i<p->binCnt; ++i)
  1639. {
  1640. cmReal_t dPhs = phsV[i] - p->phsV[i];
  1641. // unwrap phase - see phase_study.m for explanation
  1642. cmReal_t k = round( (p->wV[i] - dPhs) / twoPi);
  1643. // convert phase change to Hz
  1644. p->hzV[i] = (k * twoPi + dPhs) * p->srate / den;
  1645. // store phase for next iteration
  1646. p->phsV[i] = phsV[i];
  1647. }
  1648. return rc;
  1649. }
  1650. //------------------------------------------------------------------------------------------------------------
  1651. cmPvAnl* cmPvAnlAlloc( cmCtx* ctx, cmPvAnl* ap, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopSmpCnt, unsigned flags )
  1652. {
  1653. cmRC_t rc;
  1654. cmPvAnl* p = cmObjAlloc( cmPvAnl, ctx, ap );
  1655. cmShiftBufAlloc(ctx, &p->sb, procSmpCnt, wndSmpCnt, hopSmpCnt );
  1656. cmWndFuncAlloc( ctx, &p->wf, kHannWndId, wndSmpCnt, 0);
  1657. cmFftAllocSR( ctx, &p->ft, p->wf.outV, wndSmpCnt, kToPolarFftFl);
  1658. cmPhsToFrqAlloc(ctx, &p->pf, srate, p->ft.binCnt, hopSmpCnt );
  1659. if( procSmpCnt > 0 )
  1660. if((rc = cmPvAnlInit(p,procSmpCnt,srate,wndSmpCnt,hopSmpCnt,flags)) != cmOkRC )
  1661. cmPvAnlFree(&p);
  1662. return p;
  1663. }
  1664. cmRC_t cmPvAnlFree( cmPvAnl** pp )
  1665. {
  1666. cmRC_t rc;
  1667. if( pp==NULL || *pp==NULL )
  1668. return cmOkRC;
  1669. cmPvAnl* p = *pp;
  1670. if((rc = cmPvAnlFinal(p) ) != cmOkRC )
  1671. return rc;
  1672. cmObjFreeStatic( cmPhsToFrqFree, cmPhsToFrq, p->pf );
  1673. cmObjFreeStatic( cmFftFreeSR, cmFftSR, p->ft );
  1674. cmObjFreeStatic( cmWndFuncFree, cmWndFunc, p->wf );
  1675. cmObjFreeStatic( cmShiftBufFree, cmShiftBuf, p->sb );
  1676. cmObjFree(pp);
  1677. return rc;
  1678. }
  1679. cmRC_t cmPvAnlInit( cmPvAnl* p, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopSmpCnt, unsigned flags )
  1680. {
  1681. cmRC_t rc;
  1682. if((rc = cmPvAnlFinal(p)) != cmOkRC )
  1683. return rc;
  1684. if((rc = cmShiftBufInit( &p->sb, procSmpCnt, wndSmpCnt, hopSmpCnt )) != cmOkRC )
  1685. return rc;
  1686. if((rc = cmWndFuncInit( &p->wf, kHannWndId | kNormByLengthWndFl, wndSmpCnt, 0)) != cmOkRC )
  1687. return rc;
  1688. if((rc = cmFftInitSR( &p->ft, p->wf.outV, wndSmpCnt, kToPolarFftFl)) != cmOkRC )
  1689. return rc;
  1690. if((rc = cmPhsToFrqInit( &p->pf, srate, p->ft.binCnt, hopSmpCnt)) != cmOkRC )
  1691. return rc;
  1692. // if the window was just initialized
  1693. // divide the window to indirectly apply the magnitude normalization
  1694. //if( p->wndSmpCnt != wndSmpCnt )
  1695. // cmVOS_DivVS( p->wf.wndV, p->wf.outN, wndSmpCnt );
  1696. p->flags = flags;
  1697. p->procSmpCnt = procSmpCnt;
  1698. p->wndSmpCnt = wndSmpCnt;
  1699. p->hopSmpCnt = hopSmpCnt;
  1700. p->binCnt = p->ft.binCnt;
  1701. p->magV = p->ft.magV;
  1702. p->phsV = p->ft.phsV;
  1703. p->hzV = p->pf.hzV;
  1704. return rc;
  1705. }
  1706. cmRC_t cmPvAnlFinal(cmPvAnl* p )
  1707. { return cmOkRC; }
  1708. bool cmPvAnlExec( cmPvAnl* p, const cmSample_t* x, unsigned xN )
  1709. {
  1710. bool fl = false;
  1711. while( cmShiftBufExec(&p->sb,x,xN) )
  1712. {
  1713. cmWndFuncExec(&p->wf, p->sb.outV, p->sb.wndSmpCnt );
  1714. cmFftExecSR(&p->ft,NULL,0);
  1715. if( cmIsFlag(p->flags,kCalcHzPvaFl) )
  1716. cmPhsToFrqExec(&p->pf,p->phsV);
  1717. fl = true;
  1718. }
  1719. return fl;
  1720. }
  1721. //------------------------------------------------------------------------------------------------------------
  1722. cmPvSyn* cmPvSynAlloc( cmCtx* ctx, cmPvSyn* ap, unsigned procSmpCnt, double outSrate, unsigned wndSmpCnt, unsigned hopSmpCnt, unsigned wndTypeId )
  1723. {
  1724. cmRC_t rc;
  1725. cmPvSyn* p = cmObjAlloc( cmPvSyn, ctx, ap );
  1726. cmWndFuncAlloc( ctx, &p->wf, kHannWndId, wndSmpCnt, 0);
  1727. cmIFftAllocRS( ctx, &p->ft, wndSmpCnt/2+1 );
  1728. cmOlaAlloc( ctx, &p->ola, wndSmpCnt, hopSmpCnt, procSmpCnt, wndTypeId );
  1729. if( procSmpCnt )
  1730. if((rc = cmPvSynInit(p,procSmpCnt,outSrate,wndSmpCnt,hopSmpCnt,wndTypeId)) != cmOkRC )
  1731. cmPvSynFree(&p);
  1732. return p;
  1733. }
  1734. cmRC_t cmPvSynFree( cmPvSyn** pp )
  1735. {
  1736. cmRC_t rc;
  1737. if( pp==NULL || *pp==NULL )
  1738. return cmOkRC;
  1739. cmPvSyn* p = *pp;
  1740. if((rc = cmPvSynFinal(p)) != cmOkRC )
  1741. return rc;
  1742. cmMemPtrFree(&p->minRphV);
  1743. cmMemPtrFree(&p->maxRphV);
  1744. cmMemPtrFree(&p->itrV);
  1745. cmMemPtrFree(&p->phs0V);
  1746. cmMemPtrFree(&p->phsV);
  1747. cmMemPtrFree(&p->mag0V);
  1748. cmMemPtrFree(&p->magV);
  1749. cmObjFreeStatic( cmOlaFree, cmOla, p->ola);
  1750. cmObjFreeStatic( cmIFftFreeRS, cmIFftRS, p->ft );
  1751. cmObjFreeStatic( cmWndFuncFree, cmWndFunc, p->wf );
  1752. cmObjFree(pp);
  1753. return cmOkRC;
  1754. }
  1755. cmRC_t cmPvSynInit( cmPvSyn* p, unsigned procSmpCnt, double outSrate, unsigned wndSmpCnt, unsigned hopSmpCnt, unsigned wndTypeId )
  1756. {
  1757. cmRC_t rc;
  1758. int k;
  1759. double twoPi = 2.0 * M_PI;
  1760. bool useHannFl = true;
  1761. int m = useHannFl ? 2 : 1;
  1762. if((rc = cmPvSynFinal(p)) != cmOkRC )
  1763. return rc;
  1764. p->outSrate = outSrate;
  1765. p->procSmpCnt = procSmpCnt;
  1766. p->wndSmpCnt = wndSmpCnt;
  1767. p->hopSmpCnt = hopSmpCnt;
  1768. p->binCnt = wndSmpCnt / 2 + 1;
  1769. p->minRphV = cmMemResizeZ( cmReal_t, p->minRphV, p->binCnt );
  1770. p->maxRphV = cmMemResizeZ( cmReal_t, p->maxRphV, p->binCnt );
  1771. p->itrV = cmMemResizeZ( cmReal_t, p->itrV, p->binCnt );
  1772. p->phs0V = cmMemResizeZ( cmReal_t, p->phs0V, p->binCnt );
  1773. p->phsV = cmMemResizeZ( cmReal_t, p->phsV, p->binCnt );
  1774. p->mag0V = cmMemResizeZ( cmReal_t, p->mag0V, p->binCnt );
  1775. p->magV = cmMemResizeZ( cmReal_t, p->magV, p->binCnt );
  1776. if((rc = cmWndFuncInit( &p->wf, wndTypeId, wndSmpCnt, 0)) != cmOkRC )
  1777. return rc;
  1778. if((rc = cmIFftInitRS( &p->ft, p->binCnt )) != cmOkRC )
  1779. return rc;
  1780. if((rc = cmOlaInit( &p->ola, wndSmpCnt, hopSmpCnt, procSmpCnt, wndTypeId )) != cmOkRC )
  1781. return rc;
  1782. for(k=0; k<p->binCnt; ++k)
  1783. {
  1784. // complete revolutions per hop in radians
  1785. p->itrV[k] = twoPi * floor((double)k * hopSmpCnt / wndSmpCnt );
  1786. p->minRphV[k] = ((cmReal_t)(k-m)) * hopSmpCnt * twoPi / wndSmpCnt;
  1787. p->maxRphV[k] = ((cmReal_t)(k+m)) * hopSmpCnt * twoPi / wndSmpCnt;
  1788. //printf("%f %f %f\n",p->itrV[k],p->minRphV[k],p->maxRphV[k]);
  1789. }
  1790. return rc;
  1791. }
  1792. cmRC_t cmPvSynFinal(cmPvSyn* p )
  1793. { return cmOkRC; }
  1794. cmRC_t cmPvSynExec( cmPvSyn* p, const cmReal_t* magV, const cmReal_t* phsV )
  1795. {
  1796. double twoPi = 2.0 * M_PI;
  1797. unsigned k;
  1798. for(k=0; k<p->binCnt; ++k)
  1799. {
  1800. // phase dist between cur and prv frame
  1801. cmReal_t dp = phsV[k] - p->phs0V[k];
  1802. // dist must be positive (accum phase always increases)
  1803. if( dp < -0.00001 )
  1804. dp += twoPi;
  1805. // add in complete revolutions based on the bin frequency
  1806. // (these would have been lost from 'dp' due to phase wrap)
  1807. dp += p->itrV[k];
  1808. // constrain the phase change to lie within the range of the kth bin
  1809. if( dp < p->minRphV[k] )
  1810. dp += twoPi;
  1811. if( dp > p->maxRphV[k] )
  1812. dp -= twoPi;
  1813. p->phsV[k] = p->phs0V[k] + dp;
  1814. p->magV[k] = p->mag0V[k];
  1815. p->phs0V[k] = phsV[k];
  1816. p->mag0V[k] = magV[k];
  1817. }
  1818. cmIFftExecPolarRS( &p->ft, magV, phsV );
  1819. cmOlaExecS( &p->ola, p->ft.outV, p->ft.outN );
  1820. //printf("%i %i\n",p->binCnt,p->ft.binCnt );
  1821. //cmVOR_Print( p->obj.ctx->outFuncPtr, 1, p->binCnt, magV );
  1822. //cmVOR_Print( p->obj.ctx->outFuncPtr, 1, p->binCnt, p->phsV );
  1823. //cmVOS_Print( p->obj.ctx->outFuncPtr, 1, 10, p->ft.outV );
  1824. return cmOkRC;
  1825. }
  1826. cmRC_t cmPvSynDoIt( cmPvSyn* p, const cmSample_t* v )
  1827. {
  1828. cmOlaExecS( &p->ola, v, p->wndSmpCnt );
  1829. //printf("%f\n",cmVOS_RMS(s,p->wndSmpCnt,p->wndSmpCnt));
  1830. return cmOkRC;
  1831. }
  1832. const cmSample_t* cmPvSynExecOut(cmPvSyn* p )
  1833. { return cmOlaExecOut(&p->ola); }
  1834. //------------------------------------------------------------------------------------------------------------
  1835. cmMidiSynth* cmMidiSynthAlloc( cmCtx* ctx, cmMidiSynth* ap, const cmMidiSynthPgm* pgmArray, unsigned pgmCnt, unsigned voiceCnt, unsigned procSmpCnt, unsigned outChCnt, cmReal_t srate )
  1836. {
  1837. cmMidiSynth* p = cmObjAlloc( cmMidiSynth, ctx, ap );
  1838. if( pgmArray != NULL )
  1839. if( cmMidiSynthInit( p, pgmArray, pgmCnt, voiceCnt, procSmpCnt, outChCnt, srate ) != cmOkRC )
  1840. cmMidiSynthFree(&p);
  1841. return p;
  1842. }
  1843. cmRC_t cmMidiSynthFree( cmMidiSynth** pp )
  1844. {
  1845. cmRC_t rc;
  1846. if( pp==NULL || *pp==NULL)
  1847. return cmOkRC;
  1848. cmMidiSynth* p = *pp;
  1849. if((rc = cmMidiSynthFinal(p)) != cmOkRC )
  1850. return rc;
  1851. cmMemPtrFree(&p->voiceArray);
  1852. cmMemPtrFree(&p->outM);
  1853. cmMemPtrFree(&p->outChArray);
  1854. cmObjFree(pp);
  1855. return cmOkRC;
  1856. }
  1857. cmRC_t cmMidiSynthInit( cmMidiSynth* p, const cmMidiSynthPgm* pgmArray, unsigned pgmCnt, unsigned voiceCnt, unsigned procSmpCnt, unsigned outChCnt, cmReal_t srate )
  1858. {
  1859. // at least one pgm must be given
  1860. assert( pgmCnt > 0 );
  1861. unsigned i;
  1862. cmRC_t rc;
  1863. if((rc = cmMidiSynthFinal(p)) != cmOkRC )
  1864. return rc;
  1865. p->voiceArray = cmMemResizeZ( cmMidiVoice, p->voiceArray, voiceCnt );
  1866. p->outM = cmMemResizeZ( cmSample_t, p->outM, outChCnt * procSmpCnt );
  1867. p->outChArray = cmMemResizeZ( cmSample_t*, p->outChArray, outChCnt );
  1868. p->avail = p->voiceArray;
  1869. p->voiceCnt = voiceCnt;
  1870. p->activeVoiceCnt = 0;
  1871. p->voiceStealCnt = 0;
  1872. p->procSmpCnt = procSmpCnt;
  1873. p->outChCnt = outChCnt;
  1874. p->srate = srate;
  1875. for(i=0; i<outChCnt; ++i)
  1876. p->outChArray[i] = p->outM + (i*procSmpCnt);
  1877. for(i=0; i<kMidiChCnt; ++i)
  1878. {
  1879. p->chArray[i].pgm = 0;
  1880. p->chArray[i].active = NULL;
  1881. p->chArray[i].pitchBend = 0;
  1882. p->chArray[i].synthPtr = p;
  1883. memset(p->chArray[i].midiCtl, 0, kMidiCtlCnt * sizeof(cmMidiByte_t));
  1884. }
  1885. for(i=0; i<voiceCnt; ++i)
  1886. {
  1887. p->voiceArray[i].index = i;
  1888. p->voiceArray[i].flags = 0;
  1889. p->voiceArray[i].pitch = kInvalidMidiPitch;
  1890. p->voiceArray[i].velocity = kInvalidMidiVelocity;
  1891. p->voiceArray[i].pgm.pgm = kInvalidMidiPgm;
  1892. p->voiceArray[i].pgm.cbPtr = NULL;
  1893. p->voiceArray[i].pgm.cbDataPtr = NULL;
  1894. p->voiceArray[i].chPtr = NULL;
  1895. p->voiceArray[i].link = i<voiceCnt-1 ? p->voiceArray + i + 1 : NULL;
  1896. }
  1897. for(i=0; i<pgmCnt; ++i)
  1898. {
  1899. unsigned idx = pgmArray[i].pgm;
  1900. if( idx >= kMidiPgmCnt )
  1901. rc = cmCtxRtCondition( &p->obj, cmArgAssertRC, "MIDI program change values must be less than %i.",kMidiPgmCnt);
  1902. else
  1903. {
  1904. p->pgmArray[ idx ].cbPtr = pgmArray[i].cbPtr;
  1905. p->pgmArray[ idx ].cbDataPtr = pgmArray[i].cbDataPtr;
  1906. p->pgmArray[ idx ].pgm = idx;
  1907. }
  1908. }
  1909. return rc;
  1910. }
  1911. cmRC_t cmMidiSynthFinal( cmMidiSynth* p )
  1912. { return cmOkRC; }
  1913. cmRC_t _cmMidiSynthOnNoteOn( cmMidiSynth* p, cmMidiByte_t ch, cmMidiByte_t pitch, cmMidiByte_t vel )
  1914. {
  1915. assert( ch < kMidiChCnt );
  1916. if( p->activeVoiceCnt == p->voiceCnt )
  1917. {
  1918. ++p->voiceStealCnt;
  1919. return cmOkRC;
  1920. }
  1921. assert( p->avail != NULL );
  1922. cmMidiSynthCh* chPtr = p->chArray + ch;
  1923. cmMidiVoice* vp = p->avail;
  1924. ++p->activeVoiceCnt;
  1925. // update avail
  1926. p->avail = p->avail->link;
  1927. // update active
  1928. vp->flags |= kActiveMsFl | kKeyGateMsFl;
  1929. vp->pitch = pitch;
  1930. vp->velocity = vel;
  1931. vp->pgm = p->pgmArray[ chPtr->pgm ];
  1932. vp->chPtr = chPtr;
  1933. vp->link = chPtr->active;
  1934. chPtr->active = vp;
  1935. vp->pgm.cbPtr( vp, kAttackMsId, NULL, 0 );
  1936. return cmOkRC;
  1937. }
  1938. cmRC_t _cmMidiSynthOnNoteOff( cmMidiSynth* p, cmMidiByte_t ch, cmMidiByte_t pitch, cmMidiByte_t vel )
  1939. {
  1940. assert( ch < kMidiChCnt );
  1941. cmMidiSynthCh* cp = p->chArray + ch;
  1942. cmMidiVoice* vp = cp->active;
  1943. // find the voice for the given pitch
  1944. while( vp != NULL )
  1945. {
  1946. if( (vp->pitch == pitch) && (cmIsFlag(vp->flags,kKeyGateMsFl)==true) )
  1947. break;
  1948. vp = vp->link;
  1949. }
  1950. // if no voice had a key down on this pitch
  1951. if( vp == NULL )
  1952. {
  1953. return cmOkRC;
  1954. }
  1955. // mark the key as 'up'
  1956. vp->flags = cmClrFlag(vp->flags,kKeyGateMsFl);
  1957. // if the sustain pedal is up
  1958. if( cp->midiCtl[ kSustainCtlMdId ] == 0 )
  1959. vp->pgm.cbPtr( vp, kReleaseMsId, NULL, 0 );
  1960. return cmOkRC;
  1961. }
  1962. cmRC_t _cmMidiSynthOnCtl( cmMidiSynth* p, cmMidiByte_t ch, cmMidiByte_t ctlId, cmMidiByte_t ctlValue )
  1963. {
  1964. assert( ch < kMidiChCnt && ctlId < kMidiCtlCnt );
  1965. cmMidiSynthCh* cp = p->chArray + ch;
  1966. cp->midiCtl[ ctlId ] = ctlValue;
  1967. // if the sustain pedal is going up
  1968. if( ctlId == kSustainCtlMdId && ctlValue == 0 )
  1969. {
  1970. cmMidiVoice* vp = cp->active;
  1971. while(vp != NULL)
  1972. {
  1973. if( cmIsFlag(vp->flags,kKeyGateMsFl)==false )
  1974. vp->pgm.cbPtr(vp, kReleaseMsId, NULL, 0 );
  1975. vp = vp->link;
  1976. }
  1977. }
  1978. //printf("%i %i %f\n",ctlId,ctlValue,ctlValue/127.0);
  1979. return cmOkRC;
  1980. }
  1981. cmRC_t cmMidiSynthOnMidi( cmMidiSynth* p, const cmMidiPacket_t* pktArray, unsigned pktCnt )
  1982. {
  1983. unsigned i=0;
  1984. for(i=0; i<pktCnt; ++i)
  1985. if( pktArray[i].msgArray != NULL )
  1986. {
  1987. unsigned j;
  1988. for(j=0; j<pktArray[i].msgCnt; ++j)
  1989. {
  1990. const cmMidiMsg* mp = pktArray[i].msgArray + j;
  1991. cmMidiByte_t ch = mp->status & 0x0f;
  1992. cmMidiByte_t status = mp->status & 0xf0;
  1993. switch( status )
  1994. {
  1995. case kNoteOnMdId:
  1996. if( mp->d1 != 0 )
  1997. {
  1998. _cmMidiSynthOnNoteOn(p,ch,mp->d0,mp->d1);
  1999. break;
  2000. }
  2001. // fall through
  2002. case kNoteOffMdId:
  2003. _cmMidiSynthOnNoteOff(p,ch,mp->d0,mp->d1);
  2004. break;
  2005. case kPolyPresMdId:
  2006. break;
  2007. case kCtlMdId:
  2008. _cmMidiSynthOnCtl( p, ch, mp->d0, mp->d1 );
  2009. break;
  2010. case kPgmMdId:
  2011. break;
  2012. case kChPresMdId:
  2013. break;
  2014. case kPbendMdId:
  2015. break;
  2016. default:
  2017. printf("Unknown MIDI status:%i %i\n",(int)status,(int)mp->status);
  2018. break;
  2019. }
  2020. }
  2021. }
  2022. return cmOkRC;
  2023. }
  2024. cmRC_t cmMidiSynthExec( cmMidiSynth* p, cmSample_t* outChArray[], unsigned outChCnt )
  2025. {
  2026. unsigned i;
  2027. cmSample_t** chArray = outChArray == NULL ? p->outChArray : outChArray;
  2028. unsigned chCnt = outChArray == NULL ? p->outChCnt : outChCnt;
  2029. // FIX: make one active chain attached to cmMidiSynth rather than many
  2030. // active chains attached to each channel - this will avoid the extra
  2031. // iterations below.
  2032. // for each channel
  2033. for(i=0; i<kMidiChCnt; ++i)
  2034. {
  2035. cmMidiVoice* vp = p->chArray[i].active;
  2036. cmMidiVoice* prv = NULL;
  2037. // for each voice assigned to this channel
  2038. while(vp != NULL)
  2039. {
  2040. // tell the voice to perform its DSP function - returns 0 if the voice is no longer active
  2041. if( vp->pgm.cbPtr( vp, kDspMsId, chArray, chCnt ) )
  2042. {
  2043. prv = vp;
  2044. vp = vp->link;
  2045. }
  2046. else
  2047. {
  2048. cmMidiVoice* nvp = vp->link;
  2049. // remove vp from the active chain
  2050. if( prv != NULL )
  2051. prv->link = vp->link;
  2052. else
  2053. {
  2054. assert( vp == p->chArray[i].active );
  2055. // vp is first recd on active chain, nvp becomes first ...
  2056. p->chArray[i].active = vp->link;
  2057. prv = NULL; // ... so prv must be NULL
  2058. }
  2059. // insert this voice on the available chain
  2060. vp->link = p->avail;
  2061. p->avail = vp;
  2062. --p->activeVoiceCnt;
  2063. vp = nvp;
  2064. }
  2065. }
  2066. }
  2067. return cmOkRC;
  2068. }
  2069. //------------------------------------------------------------------------------------------------------------
  2070. cmWtVoice* cmWtVoiceAlloc( cmCtx* ctx, cmWtVoice* ap, unsigned procSmpCnt, cmReal_t hz )
  2071. {
  2072. cmWtVoice* p = cmObjAlloc( cmWtVoice, ctx, ap );
  2073. if( procSmpCnt != 0 )
  2074. if( cmWtVoiceInit( p, procSmpCnt, hz ) != cmOkRC )
  2075. cmWtVoiceFree(&p);
  2076. return p;
  2077. }
  2078. cmRC_t cmWtVoiceFree( cmWtVoice** pp )
  2079. {
  2080. cmRC_t rc = cmOkRC;
  2081. if( pp==NULL || *pp==NULL )
  2082. return cmOkRC;
  2083. cmWtVoice* p = *pp;
  2084. if((rc = cmWtVoiceFinal(p)) != cmOkRC )
  2085. return rc;
  2086. cmMemPtrFree(&p->outV);
  2087. cmObjFree(pp);
  2088. return rc;
  2089. }
  2090. cmRC_t cmWtVoiceInit( cmWtVoice* p, unsigned procSmpCnt, cmReal_t hz )
  2091. {
  2092. p->outV = cmMemResizeZ( cmSample_t, p->outV, procSmpCnt );
  2093. p->outN = procSmpCnt;
  2094. p->hz = hz;
  2095. p->level = 0;
  2096. p->durSmpCnt = 0;
  2097. p->phase = 0;
  2098. p->state = kOffWtId;
  2099. return cmOkRC;
  2100. }
  2101. cmRC_t cmWtVoiceFinal( cmWtVoice* p )
  2102. { return cmOkRC; }
  2103. int cmWtVoiceExec( cmWtVoice* p, struct cmMidiVoice_str* mvp, unsigned sel, cmSample_t* outChArray[], unsigned outChCnt )
  2104. {
  2105. switch( sel )
  2106. {
  2107. case kAttackMsId:
  2108. p->state = kAtkWtId;
  2109. p->hz = (13.75 * pow(2,(-9.0/12.0))) * pow(2,((double)mvp->pitch / 12));
  2110. //printf("%fhz\n",p->hz);
  2111. break;
  2112. case kReleaseMsId:
  2113. p->state = kRlsWtId;
  2114. //printf("rls:%f\n",p->phase);
  2115. break;
  2116. case kDspMsId:
  2117. {
  2118. if( p->state == kRlsWtId )
  2119. {
  2120. p->state = kOffWtId;
  2121. return 0;
  2122. }
  2123. cmMidiSynth* sp = mvp->chPtr->synthPtr;
  2124. cmSample_t* dp = outChCnt == 0 ? p->outV : outChArray[0];
  2125. cmSample_t* ep = dp + p->outN;
  2126. cmReal_t rps = (2.0 * M_PI * p->hz) / sp->srate;
  2127. cmReal_t sum=0;
  2128. unsigned i=0;
  2129. for(; dp < ep; ++dp)
  2130. {
  2131. *dp += (cmSample_t)(0.5 * sin( p->phase ));
  2132. sum += *dp;
  2133. ++i;
  2134. p->phase += rps;
  2135. }
  2136. //printf("(%f %f %i %i %p) ",p->phase,sum,i,p->outN,outChArray[0] );
  2137. }
  2138. break;
  2139. default:
  2140. assert(0);
  2141. break;
  2142. }
  2143. return 1;
  2144. }
  2145. //------------------------------------------------------------------------------------------------------------
  2146. cmWtVoiceBank* cmWtVoiceBankAlloc( cmCtx* ctx, cmWtVoiceBank* ap, double srate, unsigned procSmpCnt, unsigned voiceCnt, unsigned chCnt )
  2147. {
  2148. cmWtVoiceBank* p = cmObjAlloc( cmWtVoiceBank, ctx, ap );
  2149. if( srate != 0 )
  2150. if( cmWtVoiceBankInit( p, srate, procSmpCnt, voiceCnt, chCnt ) != cmOkRC )
  2151. cmWtVoiceBankFree(&p);
  2152. return p;
  2153. }
  2154. cmRC_t cmWtVoiceBankFree( cmWtVoiceBank** pp )
  2155. {
  2156. cmRC_t rc;
  2157. if( pp==NULL || *pp==NULL)
  2158. return cmOkRC;
  2159. cmWtVoiceBank* p = *pp;
  2160. if((rc = cmWtVoiceBankFinal(p)) != cmOkRC )
  2161. return rc;
  2162. cmMemPtrFree(&p->voiceArray);
  2163. cmMemPtrFree(&p->chArray);
  2164. cmMemPtrFree(&p->buf);
  2165. cmObjFree(pp);
  2166. return rc;
  2167. }
  2168. cmRC_t cmWtVoiceBankInit( cmWtVoiceBank* p, double srate, unsigned procSmpCnt, unsigned voiceCnt, unsigned chCnt )
  2169. {
  2170. cmRC_t rc;
  2171. unsigned i;
  2172. if((rc = cmWtVoiceBankFinal(p)) != cmOkRC )
  2173. return rc;
  2174. p->voiceArray = cmMemResizeZ( cmWtVoice*, p->voiceArray, voiceCnt );
  2175. for(i=0; i<voiceCnt; ++i)
  2176. p->voiceArray[i] = cmWtVoiceAlloc(p->obj.ctx,NULL,procSmpCnt,0);
  2177. p->voiceCnt = voiceCnt;
  2178. p->buf = cmMemResizeZ( cmSample_t, p->buf, chCnt * procSmpCnt );
  2179. p->chArray = cmMemResizeZ( cmSample_t*, p->chArray, chCnt );
  2180. for(i=0; i<chCnt; ++i)
  2181. p->chArray[i] = p->buf + (i*procSmpCnt);
  2182. p->chCnt = chCnt;
  2183. p->procSmpCnt = procSmpCnt;
  2184. return cmOkRC;
  2185. }
  2186. cmRC_t cmWtVoiceBankFinal( cmWtVoiceBank* p )
  2187. {
  2188. unsigned i;
  2189. for(i=0; i<p->voiceCnt; ++i)
  2190. cmWtVoiceFree(&p->voiceArray[i]);
  2191. return cmOkRC;
  2192. }
  2193. int cmWtVoiceBankExec( cmWtVoiceBank* p, struct cmMidiVoice_str* voicePtr, unsigned sel, cmSample_t* outChArray[], unsigned outChCnt )
  2194. {
  2195. cmWtVoice* vp = p->voiceArray[ voicePtr->index ];
  2196. bool fl = outChArray==NULL || outChCnt==0;
  2197. cmSample_t** chArray = fl ? p->chArray : outChArray;
  2198. unsigned chCnt = fl ? p->chCnt : outChCnt;
  2199. return cmWtVoiceExec( vp, voicePtr, sel, chArray, chCnt );
  2200. }
  2201. //------------------------------------------------------------------------------------------------------------
  2202. cmAudioFileBuf* cmAudioFileBufAlloc( cmCtx* ctx, cmAudioFileBuf* ap, unsigned procSmpCnt, const char* fn, unsigned audioChIdx, unsigned begSmpIdx, unsigned durSmpCnt )
  2203. {
  2204. cmAudioFileBuf* p = cmObjAlloc( cmAudioFileBuf, ctx, ap );
  2205. if( procSmpCnt != 0 )
  2206. if( cmAudioFileBufInit( p, procSmpCnt, fn, audioChIdx, begSmpIdx, durSmpCnt ) != cmOkRC )
  2207. cmAudioFileBufFree(&p);
  2208. return p;
  2209. }
  2210. cmRC_t cmAudioFileBufFree( cmAudioFileBuf** pp )
  2211. {
  2212. cmRC_t rc;
  2213. if( pp==NULL || *pp==NULL)
  2214. return cmOkRC;
  2215. cmAudioFileBuf* p = *pp;
  2216. if((rc = cmAudioFileBufFinal(p)) != cmOkRC )
  2217. return rc;
  2218. cmMemPtrFree(&p->bufV);
  2219. cmMemPtrFree(&p->fn);
  2220. cmObjFree(pp);
  2221. return rc;
  2222. }
  2223. cmRC_t cmAudioFileBufInit( cmAudioFileBuf* p, unsigned procSmpCnt, const char* fn, unsigned audioChIdx, unsigned begSmpIdx, unsigned durSmpCnt )
  2224. {
  2225. cmAudioFileH_t afH;
  2226. cmRC_t rc;
  2227. if((rc = cmAudioFileBufFinal(p)) != cmOkRC )
  2228. return rc;
  2229. // open the audio file for reading
  2230. if( cmAudioFileIsValid( afH = cmAudioFileNewOpen( fn, &p->info, &rc, p->obj.err.rpt ))==false || rc != kOkAfRC )
  2231. return cmCtxRtCondition(&p->obj, cmArgAssertRC,"The audio file '%s' could not be opend.",fn );
  2232. // validate the audio channel
  2233. if( audioChIdx >= p->info.chCnt )
  2234. return cmCtxRtCondition(&p->obj, cmArgAssertRC,"The audio file channel index %i is out of range for the audio file '%s'.",audioChIdx,fn);
  2235. // validate the start sample index
  2236. if( begSmpIdx > p->info.frameCnt )
  2237. return cmCtxRtCondition(&p->obj, cmOkRC, "The start sample index %i is past the end of the audio file '%s'.",begSmpIdx,fn);
  2238. if( durSmpCnt == cmInvalidCnt )
  2239. durSmpCnt = p->info.frameCnt - begSmpIdx;
  2240. // validate the duration
  2241. if( begSmpIdx + durSmpCnt > p->info.frameCnt )
  2242. {
  2243. unsigned newDurSmpCnt = p->info.frameCnt - begSmpIdx;
  2244. cmCtxRtCondition(&p->obj, cmOkRC, "The selected sample duration %i is past the end of the audio file '%s' and has been shorted to %i samples.",durSmpCnt,fn,newDurSmpCnt);
  2245. durSmpCnt = newDurSmpCnt;
  2246. }
  2247. // seek to the starting sample
  2248. if( cmAudioFileSeek( afH, begSmpIdx ) != kOkAfRC )
  2249. return cmCtxRtCondition(&p->obj, cmArgAssertRC,"Seek to sample index %i failed on the audio file '%s'.",begSmpIdx,fn);
  2250. // allocate the buffer memory
  2251. p->bufV = cmMemResizeZ( cmSample_t, p->bufV, durSmpCnt );
  2252. p->fn = cmMemResize( char, p->fn, strlen(fn)+1 );
  2253. p->bufN = durSmpCnt;
  2254. p->begSmpIdx = begSmpIdx;
  2255. p->chIdx = audioChIdx;
  2256. strcpy(p->fn,fn);
  2257. cmSample_t* outV = p->bufV;
  2258. // read the file into the buffer
  2259. unsigned rdSmpCnt = cmMin(4096,durSmpCnt);
  2260. unsigned cmc = 0;
  2261. while( cmc < durSmpCnt )
  2262. {
  2263. unsigned actualReadCnt = 0;
  2264. unsigned n = rdSmpCnt;
  2265. cmSample_t* chArray[] = {outV};
  2266. if( cmc + n > durSmpCnt )
  2267. n = durSmpCnt - cmc;
  2268. if((rc=cmAudioFileReadSample( afH, n, audioChIdx, 1, chArray, &actualReadCnt)) != kOkAfRC )
  2269. break;
  2270. cmc += actualReadCnt;
  2271. outV += actualReadCnt;
  2272. }
  2273. if( rc==kOkAfRC || (rc != kOkAfRC && cmAudioFileIsEOF(afH)))
  2274. rc = cmOkRC;
  2275. return rc;
  2276. }
  2277. cmRC_t cmAudioFileBufFinal(cmAudioFileBuf* p )
  2278. { return cmOkRC; }
  2279. unsigned cmAudioFileBufExec( cmAudioFileBuf* p, unsigned smpIdx, cmSample_t* outV, unsigned outN, bool sumIntoOutFl )
  2280. {
  2281. if( outV == NULL || outN == 0 || smpIdx >= p->bufN )
  2282. return 0;
  2283. unsigned n = cmMin(outN,p->bufN-smpIdx);
  2284. if( sumIntoOutFl )
  2285. cmVOS_AddVV(outV,n,p->bufV + smpIdx);
  2286. else
  2287. cmVOS_Copy(outV,n,p->bufV + smpIdx );
  2288. if( n < outN )
  2289. memset(outV+n,0,(outN-n)*sizeof(cmSample_t));
  2290. return n;
  2291. }
  2292. //------------------------------------------------------------------------------------------------------------
  2293. cmMDelay* cmMDelayAlloc( cmCtx* ctx, cmMDelay* ap, unsigned procSmpCnt, cmReal_t srate, cmReal_t fbCoeff, unsigned delayCnt, const cmReal_t* delayMsArray, const cmReal_t* delayGainArray )
  2294. {
  2295. cmMDelay* p = cmObjAlloc( cmMDelay, ctx, ap );
  2296. if( procSmpCnt != 0 )
  2297. if( cmMDelayInit( p, procSmpCnt, srate, fbCoeff, delayCnt, delayMsArray, delayGainArray ) != cmOkRC )
  2298. cmMDelayFree(&p);
  2299. return p;
  2300. }
  2301. cmRC_t cmMDelayFree( cmMDelay** pp )
  2302. {
  2303. cmRC_t rc;
  2304. if( pp == NULL || *pp==NULL)
  2305. return cmOkRC;
  2306. cmMDelay* p = *pp;
  2307. if((rc = cmMDelayFinal(p)) != cmOkRC )
  2308. return rc;
  2309. unsigned i;
  2310. for(i=0; i<p->delayCnt; ++i)
  2311. cmMemPtrFree(&p->delayArray[i].delayBuf);
  2312. cmMemPtrFree(&p->delayArray);
  2313. cmMemPtrFree(&p->outV);
  2314. cmObjFree(pp);
  2315. return cmOkRC;
  2316. }
  2317. cmRC_t cmMDelayInit( cmMDelay* p, unsigned procSmpCnt, cmReal_t srate, cmReal_t fbCoeff, unsigned delayCnt, const cmReal_t* delayMsArray, const cmReal_t* delayGainArray )
  2318. {
  2319. cmRC_t rc;
  2320. if((rc = cmMDelayFinal(p)) != cmOkRC )
  2321. return rc;
  2322. if( delayCnt <= 0 )
  2323. return rc;
  2324. p->delayArray = cmMemResizeZ( cmMDelayHead, p->delayArray, delayCnt );
  2325. unsigned i;
  2326. for(i=0; i<delayCnt; ++i)
  2327. {
  2328. p->delayArray[i].delayGain = delayGainArray == NULL ? 1.0 : delayGainArray[i];
  2329. p->delayArray[i].delayMs = delayMsArray[i];
  2330. p->delayArray[i].delaySmpFrac = delayMsArray[i] * srate / 1000.0;
  2331. p->delayArray[i].delayBufSmpCnt = ceil(delayMsArray[i] * srate / 1000)+2;
  2332. p->delayArray[i].delayBuf = cmMemResizeZ( cmSample_t, p->delayArray[i].delayBuf, p->delayArray[i].delayBufSmpCnt );
  2333. p->delayArray[i].inIdx = 0;
  2334. }
  2335. p->delayCnt= delayCnt;
  2336. p->outV = cmMemResizeZ( cmSample_t, p->outV, procSmpCnt );
  2337. p->outN = procSmpCnt;
  2338. p->fbCoeff = fbCoeff;
  2339. p->srate = srate;
  2340. return cmOkRC;
  2341. }
  2342. cmRC_t cmMDelayFinal( cmMDelay* p )
  2343. { return cmOkRC; }
  2344. void _cmMDelayExec( cmMDelay* p, cmMDelayHead* hp, const cmSample_t inV[], cmSample_t outV[], unsigned sigN )
  2345. {
  2346. cmSample_t* dl = hp->delayBuf; // ptr to the base of the delay line
  2347. cmReal_t dfi = (cmReal_t)(hp->inIdx - hp->delaySmpFrac) + hp->delayBufSmpCnt; // fractional delay in samples
  2348. int dii0 = ((int)dfi) % hp->delayBufSmpCnt; // index to the sample just before the delay position
  2349. int dii1 = (dii0 + 1) % hp->delayBufSmpCnt; // index to the sample just after the delay position
  2350. //cmReal_t frac = 0; //dfi - dii0; // interpolation coeff.
  2351. unsigned i;
  2352. for(i=0; i<sigN; i++)
  2353. {
  2354. /*
  2355. outPtr[i] = -(((f+0)*(f-1)*(f-2)/6) * _wtPtr[iPhs0])
  2356. +(((f+1)*(f-1)*(f-2)/2) * _wtPtr[iPhs0+1])
  2357. -(((f+1)*(f-0)*(f-2)/2) * _wtPtr[iPhs0+2])
  2358. +(((f+1)*(f-0)*(f-1)/6) * _wtPtr[iPhs0+3]);
  2359. */
  2360. cmSample_t outSmp = dl[dii0]; // + (frac * (dl[dii1]-dl[dii0]));
  2361. outV[i] += outSmp/p->delayCnt;
  2362. dl[hp->inIdx] = (p->fbCoeff * outSmp) + inV[i];
  2363. hp->inIdx = (hp->inIdx+1) % hp->delayBufSmpCnt;
  2364. dii0 = (dii0+1) % hp->delayBufSmpCnt;
  2365. dii1 = (dii1+1) % hp->delayBufSmpCnt;
  2366. }
  2367. }
  2368. cmRC_t cmMDelayExec( cmMDelay* p, const cmSample_t* inV, cmSample_t* outV, unsigned sigN, bool bypassFl )
  2369. {
  2370. assert( sigN <= p->outN);
  2371. if( outV == NULL )
  2372. {
  2373. outV = p->outV;
  2374. sigN = cmMin(sigN,p->outN);
  2375. cmVOS_Fill(outV,sigN,0);
  2376. }
  2377. else
  2378. {
  2379. cmVOS_Zero(outV,sigN);
  2380. }
  2381. if( inV == NULL )
  2382. return cmOkRC;
  2383. if( bypassFl )
  2384. {
  2385. memcpy(outV,inV,sigN*sizeof(cmSample_t));
  2386. return cmOkRC;
  2387. }
  2388. unsigned di;
  2389. for( di=0; di<p->delayCnt; ++di)
  2390. {
  2391. cmMDelayHead* hp = p->delayArray + di;
  2392. hp->delaySmpFrac = hp->delayMs * p->srate / 1000.0;
  2393. _cmMDelayExec(p,hp,inV,outV,sigN);
  2394. }
  2395. return cmOkRC;
  2396. }
  2397. void cmMDelaySetTapMs( cmMDelay* p, unsigned tapIdx, cmReal_t ms )
  2398. {
  2399. assert( tapIdx < p->delayCnt );
  2400. p->delayArray[tapIdx].delayMs = ms;
  2401. }
  2402. void cmMDelaySetTapGain(cmMDelay* p, unsigned tapIdx, cmReal_t gain )
  2403. {
  2404. assert( tapIdx < p->delayCnt );
  2405. p->delayArray[tapIdx].delayGain = gain;
  2406. }
  2407. void cmMDelayReport( cmMDelay* p, cmRpt_t* rpt )
  2408. {
  2409. cmRptPrintf(rpt,"tap cnt:%i fb:%f sr:%f\n",p->delayCnt,p->fbCoeff,p->srate);
  2410. }
  2411. //------------------------------------------------------------------------------------------------------------
  2412. cmAudioSegPlayer* cmAudioSegPlayerAlloc( cmCtx* ctx, cmAudioSegPlayer* ap, unsigned procSmpCnt, unsigned outChCnt )
  2413. {
  2414. cmAudioSegPlayer* p = cmObjAlloc( cmAudioSegPlayer, ctx, ap );
  2415. if( procSmpCnt != 0 )
  2416. if( cmAudioSegPlayerInit( p, procSmpCnt, outChCnt ) != cmOkRC )
  2417. cmAudioSegPlayerFree(&p);
  2418. return p;
  2419. }
  2420. cmRC_t cmAudioSegPlayerFree( cmAudioSegPlayer** pp )
  2421. {
  2422. if( pp == NULL || *pp == NULL )
  2423. return cmOkRC;
  2424. cmAudioSegPlayer* p = *pp;
  2425. cmMemPtrFree(&p->segArray);
  2426. cmMemPtrFree(&p->outM);
  2427. cmObjFree(pp);
  2428. return cmOkRC;
  2429. }
  2430. cmRC_t cmAudioSegPlayerInit( cmAudioSegPlayer* p, unsigned procSmpCnt, unsigned outChCnt )
  2431. {
  2432. cmRC_t rc = cmOkRC;
  2433. if((rc = cmAudioSegPlayerFinal(p)) != cmOkRC )
  2434. return rc;
  2435. p->procSmpCnt = procSmpCnt;
  2436. p->outChCnt = outChCnt;
  2437. p->segCnt = 0;
  2438. if( outChCnt )
  2439. {
  2440. unsigned i;
  2441. p->outM = cmMemResizeZ( cmSample_t, p->outM, procSmpCnt * outChCnt );
  2442. p->outChArray = cmMemResizeZ( cmSample_t*, p->outChArray, outChCnt );
  2443. for(i=0; i<outChCnt; ++i)
  2444. p->outChArray[i] = p->outM + (i*procSmpCnt);
  2445. }
  2446. return rc;
  2447. }
  2448. cmRC_t cmAudioSegPlayerFinal( cmAudioSegPlayer* p )
  2449. { return cmOkRC; }
  2450. cmRC_t _cmAudioSegPlayerSegSetup( cmAudioSeg* sp, unsigned id, cmAudioFileBuf* bufPtr, unsigned smpIdx, unsigned smpCnt, unsigned outChIdx )
  2451. {
  2452. sp->bufPtr = bufPtr;
  2453. sp->id = id;
  2454. sp->smpIdx = smpIdx;
  2455. sp->smpCnt = smpCnt;
  2456. sp->outChIdx = outChIdx;
  2457. sp->outSmpIdx = 0;
  2458. sp->flags = 0;
  2459. return cmOkRC;
  2460. }
  2461. cmAudioSeg* _cmAudioSegPlayerIdToSegPtr( cmAudioSegPlayer* p, unsigned id, bool ignoreErrFl )
  2462. {
  2463. unsigned i = 0;
  2464. for(i=0; i<p->segCnt; ++i)
  2465. if( p->segArray[i].id == id )
  2466. return p->segArray + i;
  2467. if( !ignoreErrFl )
  2468. cmCtxRtCondition(&p->obj, cmArgAssertRC,"Unable to locate an audio segment with id=%i.",id);
  2469. return NULL;
  2470. }
  2471. cmRC_t cmAudioSegPlayerInsert( cmAudioSegPlayer* p, unsigned id, cmAudioFileBuf* bufPtr, unsigned smpIdx, unsigned smpCnt, unsigned outChIdx )
  2472. {
  2473. cmRC_t rc;
  2474. assert( _cmAudioSegPlayerIdToSegPtr( p, id, true ) == NULL );
  2475. p->segArray = cmMemResizePZ( cmAudioSeg, p->segArray, p->segCnt + 1 );
  2476. cmAudioSeg* sp = p->segArray + p->segCnt;
  2477. if((rc = _cmAudioSegPlayerSegSetup( sp, id, bufPtr, smpIdx, smpCnt, outChIdx )) == cmOkRC )
  2478. ++p->segCnt;
  2479. return rc;
  2480. }
  2481. cmRC_t cmAudioSegPlayerEdit( cmAudioSegPlayer* p, unsigned id, cmAudioFileBuf* bufPtr, unsigned smpIdx, unsigned smpCnt, unsigned outChIdx )
  2482. {
  2483. cmAudioSeg* sp = _cmAudioSegPlayerIdToSegPtr(p,id,false);
  2484. return _cmAudioSegPlayerSegSetup( sp, id, bufPtr, smpIdx, smpCnt, outChIdx );
  2485. }
  2486. cmRC_t cmAudioSegPlayerRemove( cmAudioSegPlayer* p, unsigned id, bool delFl )
  2487. {
  2488. cmAudioSeg* sp = _cmAudioSegPlayerIdToSegPtr(p,id,false);
  2489. if( sp == NULL )
  2490. return cmArgAssertRC;
  2491. sp->flags = cmEnaFlag( sp->flags, kDelAspFl, delFl );
  2492. return cmOkRC;
  2493. }
  2494. cmRC_t cmAudioSegPlayerEnable( cmAudioSegPlayer* p, unsigned id, bool enableFl, unsigned outSmpIdx )
  2495. {
  2496. cmAudioSeg* sp = _cmAudioSegPlayerIdToSegPtr(p,id,false);
  2497. if( sp == NULL )
  2498. return cmArgAssertRC;
  2499. if( outSmpIdx != cmInvalidIdx )
  2500. sp->outSmpIdx = outSmpIdx;
  2501. sp->flags = cmEnaFlag( sp->flags, kEnableAspFl, enableFl );
  2502. return cmOkRC;
  2503. }
  2504. void _cmAudioSegPlayerResetSeg( cmAudioSeg* sp )
  2505. {
  2506. sp->outSmpIdx = 0;
  2507. sp->flags = cmClrFlag(sp->flags, kEnableAspFl );
  2508. }
  2509. cmRC_t cmAudioSegPlayerReset( cmAudioSegPlayer* p )
  2510. {
  2511. unsigned i;
  2512. for(i=0; i<p->segCnt; ++i)
  2513. {
  2514. cmAudioSeg* sp = p->segArray + i;
  2515. _cmAudioSegPlayerResetSeg(sp);
  2516. }
  2517. return cmOkRC;
  2518. }
  2519. cmRC_t cmAudioSegPlayerExec( cmAudioSegPlayer* p, cmSample_t** outChPtr, unsigned outChCnt, unsigned procSmpCnt )
  2520. {
  2521. unsigned i;
  2522. if( outChPtr == NULL || outChCnt == 0 )
  2523. {
  2524. assert( p->outChCnt > 0 );
  2525. outChPtr = p->outChArray;
  2526. outChCnt = p->outChCnt;
  2527. assert( p->procSmpCnt <= procSmpCnt );
  2528. }
  2529. for(i=0; i<p->segCnt; ++i)
  2530. {
  2531. cmAudioSeg* sp = p->segArray + i;
  2532. // if the output channel is valid and the segment is enabled and not deleted
  2533. if( sp->outChIdx < outChCnt && (sp->flags & (kEnableAspFl | kDelAspFl)) == kEnableAspFl )
  2534. {
  2535. unsigned bufSmpIdx = sp->smpIdx + sp->outSmpIdx;
  2536. unsigned bufSmpCnt = 0;
  2537. // if all the samples have been played
  2538. if( sp->bufPtr->bufN <= bufSmpIdx )
  2539. _cmAudioSegPlayerResetSeg(sp);
  2540. else
  2541. {
  2542. // prevent playing past the end of the buffer
  2543. bufSmpCnt = cmMin( procSmpCnt, sp->bufPtr->bufN - bufSmpIdx );
  2544. // limit the number of samples to the segment length
  2545. bufSmpCnt = cmMin( bufSmpCnt, sp->smpCnt - sp->outSmpIdx );
  2546. // sum the samples into the output channel
  2547. cmVOS_AddVV( outChPtr[ sp->outChIdx ], bufSmpCnt, sp->bufPtr->bufV + bufSmpIdx );
  2548. // incr the next output sample index
  2549. sp->outSmpIdx += bufSmpCnt;
  2550. }
  2551. if( bufSmpCnt < procSmpCnt )
  2552. cmVOS_Zero( outChPtr[ sp->outChIdx ] + bufSmpCnt, procSmpCnt - bufSmpCnt );
  2553. }
  2554. }
  2555. return cmOkRC;
  2556. }
  2557. //------------------------------------------------------------------------------------------------------------
  2558. /*
  2559. cmCluster0* cmCluster0Alloc( cmCtx* ctx, cmCluster0* ap, unsigned stateCnt, unsigned binCnt, unsigned flags, cmCluster0DistFunc_t distFunc, void* dstUserPtr )
  2560. {
  2561. cmCluster0* p = cmObjAlloc( cmCluster0, ctx, ap );
  2562. if( stateCnt != 0 )
  2563. if( cmCluster0Init( p, stateCnt, binCnt, flags, distFunc, distUserPtr ) != cmOkRC )
  2564. cmCluster0Free(&p);
  2565. return p;
  2566. }
  2567. cmRC_t cmCluster0Free( cmCluster0** pp )
  2568. {
  2569. if( pp == NULL || *pp == NULL )
  2570. return cmOkRC;
  2571. cmCluster0* p = *pp;
  2572. cmMemPtrFree(&p->oM);
  2573. cmMemPtrFree(&p->tM);
  2574. cmMemPtrFree(&p->dV);
  2575. cmObjFree(pp);
  2576. return cmOkRC;
  2577. }
  2578. cmRC_t cmCluster0Init( cmCluster0* p, unsigned stateCnt, unsigned binCnt, unsigned flags, cmCluster0DistFunc_t distFunc, void* distUserPtr )
  2579. {
  2580. cmRC_t rc;
  2581. if((rc = cmCluster0Final(p)) != cmOkRC )
  2582. return rc;
  2583. p->oM = cmMemResizeZ( cmReal_t, p->oM, binCnt * stateCnt );
  2584. p->tM = cmMemResizeZ( cmReal_t, p->tM, stateCnt * stateCnt );
  2585. p->stateCnt = stateCnt;
  2586. p->binCnt = binCnt;
  2587. p->flags = flags;
  2588. p->distFunc = distFunc;
  2589. p->distUserPtr = distUserPtr;
  2590. p->cnt = 0;
  2591. }
  2592. cmRC_t cmCluster0Final( cmCluster0* p )
  2593. { return cmOkRC; }
  2594. cmRC_t cmCluster0Exec( cmCluster0* p, const cmReal_t* v, unsigned vn )
  2595. {
  2596. assert( vn <= p->binCnt );
  2597. ++cnt;
  2598. if( cnt <= stateCnt )
  2599. {
  2600. cmVOR_Copy( p->oM + ((cnt-1)*binCnt), vn, v );
  2601. return cmOkRC;
  2602. }
  2603. return cmOkRC;
  2604. }
  2605. */
  2606. cmNmf_t* cmNmfAlloc( cmCtx* ctx, cmNmf_t* ap, unsigned n, unsigned m, unsigned r, unsigned maxIterCnt, unsigned convergeCnt )
  2607. {
  2608. cmNmf_t* p = cmObjAlloc( cmNmf_t, ctx, ap );
  2609. if( n != 0 )
  2610. if( cmNmfInit( p, n, m, r, maxIterCnt, convergeCnt ) != cmOkRC )
  2611. cmNmfFree(&p);
  2612. return p;
  2613. }
  2614. cmRC_t cmNmfFree( cmNmf_t** pp )
  2615. {
  2616. if( pp== NULL || *pp == NULL )
  2617. return cmOkRC;
  2618. cmNmf_t* p = *pp;
  2619. cmMemPtrFree(&p->V);
  2620. cmMemPtrFree(&p->W);
  2621. cmMemPtrFree(&p->H);
  2622. cmMemPtrFree(&p->tr);
  2623. cmMemPtrFree(&p->x);
  2624. cmMemPtrFree(&p->t0nm);
  2625. cmMemPtrFree(&p->t1nm);
  2626. cmMemPtrFree(&p->Wt);
  2627. cmMemPtrFree(&p->trm);
  2628. cmMemPtrFree(&p->crm);
  2629. cmMemPtrFree(&p->c0);
  2630. cmMemPtrFree(&p->c1);
  2631. cmMemPtrFree(&p->idxV);
  2632. cmObjFree(pp);
  2633. return cmOkRC;
  2634. }
  2635. cmRC_t cmNmfInit( cmNmf_t* p, unsigned n, unsigned m, unsigned r, unsigned maxIterCnt, unsigned convergeCnt )
  2636. {
  2637. cmRC_t rc;
  2638. if((rc = cmNmfFinal(p)) != cmOkRC )
  2639. return rc;
  2640. p->n = n;
  2641. p->m = m;
  2642. p->r = r;
  2643. p->maxIterCnt = maxIterCnt;
  2644. p->convergeCnt= convergeCnt;
  2645. p->V = cmMemResizeZ(cmReal_t, p->V, n*m );
  2646. p->W = cmMemResize( cmReal_t, p->W, n*r );
  2647. p->H = cmMemResize( cmReal_t, p->H, r*m );
  2648. p->tr = cmMemResize( cmReal_t, p->tr, r );
  2649. p->x = cmMemResize( cmReal_t, p->x, r*cmMax(m,n) );
  2650. p->t0nm = cmMemResize( cmReal_t, p->t0nm, cmMax(r,n)*m );
  2651. p->Ht = p->t0nm;
  2652. p->t1nm = cmMemResize( cmReal_t, p->t1nm, n*m );
  2653. p->Wt = cmMemResize( cmReal_t, p->Wt, r*n );
  2654. p->trm = cmMemResize( cmReal_t, p->trm, r*cmMax(m,n) );
  2655. p->crm = cmMemResizeZ(unsigned, p->crm, r*m);
  2656. p->tnr = p->trm;
  2657. p->c0 = cmMemResizeZ(unsigned, p->c0, m*m);
  2658. p->c1 = cmMemResizeZ(unsigned, p->c1, m*m);
  2659. p->idxV = cmMemResizeZ(unsigned, p->idxV, m );
  2660. p->c0m = p->c0;
  2661. p->c1m = p->c1;
  2662. cmVOR_Random(p->W,n*r,0.0,1.0);
  2663. cmVOR_Random(p->H,r*m,0.0,1.0);
  2664. return rc;
  2665. }
  2666. cmRC_t cmNmfFinal(cmNmf_t* p )
  2667. { return cmOkRC; }
  2668. // NMF base on: Lee and Seung, 2001, Algo's for Non-negative Matrix Fcmtorization
  2669. // Connectivity stopping technique based on: http://www.broadinstitute.org/mpr/publications/projects/NMF/nmf.m
  2670. cmRC_t cmNmfExec( cmNmf_t* p, const cmReal_t* vM, unsigned cn )
  2671. {
  2672. cmRC_t rc = cmOkRC;
  2673. unsigned i,j,k;
  2674. unsigned n = p->n;
  2675. unsigned m = p->m;
  2676. unsigned r = p->r;
  2677. unsigned stopIter = 0;
  2678. assert(cn <= m );
  2679. // shift in the incoming columns of V[]
  2680. if( cn < m )
  2681. cmVOR_Shift(p->V, n*m, n*cn,0);
  2682. cmVOR_Copy( p->V, n*cn,vM );
  2683. // shift H[] by the same amount as V[]
  2684. if( cn < m )
  2685. cmVOR_Shift( p->H, r*m, r*cn,0);
  2686. cmVOR_Random(p->H, r*cn, 0.0, 1.0 );
  2687. cmVOU_Zero( p->c1m, m*m );
  2688. for(i=0,j=0; i<p->maxIterCnt && stopIter<p->convergeCnt; ++i)
  2689. {
  2690. // x[r,m] =repmat(sum(W,1)',1,m);
  2691. cmVOR_SumM( p->W, n, r, p->tr );
  2692. for(j=0; j<m; ++j)
  2693. cmVOR_Copy( p->x + (j*r), r, p->tr );
  2694. cmVOR_Transpose(p->Wt,p->W,n,r);
  2695. //H=H.*(W'*(V./(W*H)))./x;
  2696. cmVOR_MultMMM(p->t0nm,n,m,p->W,p->H,r); // t0nm[n,m] = W*H
  2697. cmVOR_DivVVV( p->t1nm,n*m,p->V,p->t0nm); // t1nm[n,m] = V./(W*H)
  2698. cmVOR_MultMMM(p->trm,r,m,p->Wt,p->t1nm,n); // trm[r,m] = W'*(V./(W*H))
  2699. cmVOR_MultVV(p->H,r*m,p->trm); // H[r,m] = H .* (W'*(V./(W*H)))
  2700. cmVOR_DivVV(p->H,r*m, p->x ); // H[r,m] = (H .* (W'*(V./(W*H)))) ./ x
  2701. // x[n,r]=repmat(sum(H,2)',n,1);
  2702. cmVOR_SumMN(p->H, r, m, p->tr );
  2703. for(j=0; j<n; ++j)
  2704. cmVOR_CopyN(p->x + j, r, n, p->tr, 1 );
  2705. cmVOR_Transpose(p->Ht,p->H,r,m);
  2706. // W=W.*((V./(W*H))*H')./x;
  2707. cmVOR_MultMMM(p->tnr,n,r,p->t1nm,p->Ht,m); // tnr[n,r] = (V./(W*H))*Ht
  2708. cmVOR_MultVV(p->W,n*r,p->tnr); // W[n,r] = W.*(V./(W*H))*Ht
  2709. cmVOR_DivVV(p->W,n*r,p->x); // W[n,r] = W.*(V./(W*H))*Ht ./x
  2710. if( i % 10 == 0 )
  2711. {
  2712. cmVOR_ReplaceLte( p->H, r*m, p->H, 2.2204e-16, 2.2204e-16 );
  2713. cmVOR_ReplaceLte( p->W, n*r, p->W, 2.2204e-16, 2.2204e-16 );
  2714. cmVOR_MaxIndexM( p->idxV, p->H, r, m );
  2715. unsigned mismatchCnt = 0;
  2716. for(j=0; j<m; ++j)
  2717. for(k=0; k<m; ++k)
  2718. {
  2719. unsigned c_idx = (j*m)+k;
  2720. p->c0m[ c_idx ] = p->idxV[j] == p->idxV[k];
  2721. mismatchCnt += p->c0m[ c_idx ] != p->c1m[ c_idx ];
  2722. }
  2723. if( mismatchCnt == 0 )
  2724. ++stopIter;
  2725. else
  2726. stopIter = 0;
  2727. printf("%i %i %i\n",i,stopIter,mismatchCnt);
  2728. fflush(stdout);
  2729. unsigned* tcm = p->c0m;
  2730. p->c0m = p->c1m;
  2731. p->c1m = tcm;
  2732. }
  2733. }
  2734. return rc;
  2735. }
  2736. //------------------------------------------------------------------------------------------------------------
  2737. unsigned _cmVectArrayTypeByteCnt( cmVectArray_t* p, unsigned flags )
  2738. {
  2739. switch( flags & kVaMask )
  2740. {
  2741. case kFloatVaFl: return sizeof(float);
  2742. case kDoubleVaFl: return sizeof(double);
  2743. case kIntVaFl: return sizeof(int);
  2744. case kUIntVaFl: return sizeof(unsigned);
  2745. }
  2746. if( p != NULL )
  2747. cmCtxRtCondition(&p->obj,cmInvalidArgRC,"Unknown data type.");
  2748. return 0;
  2749. }
  2750. cmRC_t _cmVectArrayAppend( cmVectArray_t* p, const void* v, unsigned typeByteCnt, unsigned valCnt )
  2751. {
  2752. cmRC_t rc = cmSubSysFailRC;
  2753. cmVectArrayVect_t* ep = NULL;
  2754. unsigned byteCnt = typeByteCnt * valCnt;
  2755. if( byteCnt == 0 || v == NULL )
  2756. return rc;
  2757. // verify that all vectors written to this vector array contain the same data type.
  2758. if( typeByteCnt != _cmVectArrayTypeByteCnt(p,p->flags) )
  2759. return cmCtxRtCondition(&p->obj,cmInvalidArgRC,"All data stored to a cmVectArray_t must be a consistent type.");
  2760. // allocate space for the link record
  2761. if((ep = cmMemAllocZ(cmVectArrayVect_t,1)) == NULL )
  2762. goto errLabel;
  2763. // allocate space for the vector data
  2764. if((ep->u.v = cmMemAlloc(char,typeByteCnt*valCnt)) == NULL )
  2765. goto errLabel;
  2766. // append the link recd to the end of the element list
  2767. if( p->ep != NULL )
  2768. p->ep->link = ep;
  2769. else
  2770. {
  2771. p->bp = ep;
  2772. p->cur = p->bp;
  2773. }
  2774. p->ep = ep;
  2775. // store the length of the vector
  2776. ep->n = valCnt;
  2777. // copy in the vector data
  2778. memcpy(ep->u.v,v,byteCnt);
  2779. // track the number of vectors stored
  2780. p->vectCnt += 1;
  2781. // track the longest data vector
  2782. if( valCnt > p->maxEleCnt )
  2783. p->maxEleCnt = valCnt;
  2784. rc = cmOkRC;
  2785. errLabel:
  2786. if(rc != cmOkRC )
  2787. {
  2788. cmMemFree(ep->u.v);
  2789. cmMemFree(ep);
  2790. }
  2791. return rc;
  2792. }
  2793. cmVectArray_t* cmVectArrayAlloc( cmCtx* ctx, unsigned flags )
  2794. {
  2795. cmRC_t rc = cmOkRC;
  2796. cmVectArray_t* p = cmObjAlloc(cmVectArray_t,ctx,NULL);
  2797. assert(p != NULL);
  2798. switch( flags & kVaMask )
  2799. {
  2800. case kIntVaFl:
  2801. p->flags |= kIntVaFl;
  2802. p->typeByteCnt = sizeof(int);
  2803. break;
  2804. case kUIntVaFl:
  2805. p->flags |= kUIntVaFl;
  2806. p->typeByteCnt = sizeof(unsigned);
  2807. break;
  2808. case kFloatVaFl:
  2809. p->flags |= kFloatVaFl;
  2810. p->typeByteCnt = sizeof(float);
  2811. break;
  2812. case kDoubleVaFl:
  2813. p->flags |= kDoubleVaFl;
  2814. p->typeByteCnt = sizeof(double);
  2815. break;
  2816. default:
  2817. rc = cmCtxRtCondition(&p->obj,cmInvalidArgRC,"The vector array value type flag was not recognized.");
  2818. }
  2819. if(rc != cmOkRC)
  2820. cmVectArrayFree(&p);
  2821. return p;
  2822. }
  2823. cmVectArray_t* cmVectArrayAllocFromFile(cmCtx* ctx, const char* fn )
  2824. {
  2825. cmRC_t rc = cmOkRC;
  2826. FILE* fp = NULL;
  2827. char* buf = NULL;
  2828. cmVectArray_t* p = NULL;
  2829. unsigned hn = 4;
  2830. unsigned hdr[hn];
  2831. // create the file
  2832. if((fp = fopen(fn,"rb")) == NULL )
  2833. {
  2834. rc = cmCtxRtCondition(&ctx->obj,cmSystemErrorRC,"The vector array file '%s' could not be opened.",cmStringNullGuard(fn));
  2835. goto errLabel;
  2836. }
  2837. if( fread(hdr,sizeof(unsigned),hn,fp) != hn )
  2838. {
  2839. rc = cmCtxRtCondition(&ctx->obj,cmSystemErrorRC,"The vector array file header could not be read from '%s'.",cmStringNullGuard(fn));
  2840. goto errLabel;
  2841. }
  2842. unsigned flags = hdr[0];
  2843. unsigned typeByteCnt = hdr[1];
  2844. unsigned vectCnt = hdr[2];
  2845. unsigned maxEleCnt = hdr[3];
  2846. unsigned i;
  2847. buf = cmMemAlloc(char,maxEleCnt*typeByteCnt);
  2848. if((p = cmVectArrayAlloc(ctx, flags )) == NULL )
  2849. goto errLabel;
  2850. for(i=0; i<vectCnt; ++i)
  2851. {
  2852. unsigned vn;
  2853. if( fread(&vn,sizeof(unsigned),1,fp) != 1 )
  2854. {
  2855. rc = cmCtxRtCondition(&p->obj,cmSystemErrorRC,"The vector array file element count read failed on vector index:%i in '%s'.",i,cmStringNullGuard(fn));
  2856. goto errLabel;
  2857. }
  2858. assert( vn <= maxEleCnt );
  2859. if( fread(buf,typeByteCnt,vn,fp) != vn )
  2860. {
  2861. rc = cmCtxRtCondition(&p->obj,cmSystemErrorRC,"The vector array data read failed on vector index:%i in '%s'.",i,cmStringNullGuard(fn));
  2862. goto errLabel;
  2863. }
  2864. if((rc = _cmVectArrayAppend(p,buf, typeByteCnt, vn )) != cmOkRC )
  2865. {
  2866. rc = cmCtxRtCondition(&p->obj,rc,"The vector array data store failed on vector index:%i in '%s'.",i,cmStringNullGuard(fn));
  2867. goto errLabel;
  2868. }
  2869. }
  2870. errLabel:
  2871. if( fp != NULL )
  2872. fclose(fp);
  2873. cmMemFree(buf);
  2874. if(rc != cmOkRC && p != NULL)
  2875. cmVectArrayFree(&p);
  2876. return p;
  2877. }
  2878. cmRC_t cmVectArrayFree( cmVectArray_t** pp )
  2879. {
  2880. cmRC_t rc = cmOkRC;
  2881. if( pp == NULL || *pp == NULL )
  2882. return rc;
  2883. cmVectArray_t* p = *pp;
  2884. if((rc = cmVectArrayClear(p)) != cmOkRC )
  2885. return rc;
  2886. cmMemFree(p->tempV);
  2887. cmObjFree(pp);
  2888. return rc;
  2889. }
  2890. cmRC_t cmVectArrayClear( cmVectArray_t* p )
  2891. {
  2892. cmVectArrayVect_t* ep = p->bp;
  2893. while( ep!=NULL )
  2894. {
  2895. cmVectArrayVect_t* np = ep->link;
  2896. cmMemFree(ep->u.v);
  2897. cmMemFree(ep);
  2898. ep = np;
  2899. }
  2900. p->bp = NULL;
  2901. p->ep = NULL;
  2902. p->maxEleCnt = 0;
  2903. p->vectCnt = 0;
  2904. return cmOkRC;
  2905. }
  2906. unsigned cmVectArrayCount( const cmVectArray_t* p )
  2907. { return p->vectCnt; }
  2908. unsigned cmVectArrayMaxRowCount( const cmVectArray_t* p )
  2909. {
  2910. const cmVectArrayVect_t* np = p->bp;
  2911. unsigned maxN = 0;
  2912. for(; np!=NULL; np=np->link)
  2913. if( np->n > maxN )
  2914. maxN = np->n;
  2915. return maxN;
  2916. }
  2917. cmRC_t cmVectArrayAppendV( cmVectArray_t* p, const void* v, unsigned vn )
  2918. { return _cmVectArrayAppend(p,v,_cmVectArrayTypeByteCnt(p,p->flags), vn); }
  2919. cmRC_t cmVectArrayAppendS( cmVectArray_t* p, const cmSample_t* v, unsigned vn )
  2920. { return _cmVectArrayAppend(p,v,sizeof(v[0]),vn); }
  2921. cmRC_t cmVectArrayAppendR( cmVectArray_t* p, const cmReal_t* v, unsigned vn )
  2922. { return _cmVectArrayAppend(p,v,sizeof(v[0]),vn); }
  2923. cmRC_t cmVectArrayAppendF( cmVectArray_t* p, const float* v, unsigned vn )
  2924. { return _cmVectArrayAppend(p,v,sizeof(v[0]),vn); }
  2925. cmRC_t cmVectArrayAppendD( cmVectArray_t* p, const double* v, unsigned vn )
  2926. { return _cmVectArrayAppend(p,v,sizeof(v[0]),vn); }
  2927. cmRC_t cmVectArrayAppendI( cmVectArray_t* p, const int* v, unsigned vn )
  2928. { return _cmVectArrayAppend(p,v,sizeof(v[0]),vn); }
  2929. cmRC_t cmVectArrayAppendU( cmVectArray_t* p, const unsigned* v, unsigned vn )
  2930. { return _cmVectArrayAppend(p,v,sizeof(v[0]),vn); }
  2931. cmRC_t cmVectArrayWrite( cmVectArray_t* p, const char* fn )
  2932. {
  2933. cmRC_t rc = cmOkRC;
  2934. FILE* fp = NULL;
  2935. cmVectArrayVect_t* ep;
  2936. unsigned i;
  2937. unsigned hn = 4;
  2938. unsigned hdr[hn];
  2939. hdr[0] = p->flags;
  2940. hdr[1] = p->typeByteCnt;
  2941. hdr[2] = p->vectCnt;
  2942. hdr[3] = p->maxEleCnt;
  2943. // create the file
  2944. if((fp = fopen(fn,"wb")) == NULL )
  2945. return cmCtxRtCondition(&p->obj,cmSystemErrorRC,"The vector array file '%s' could not be created.",cmStringNullGuard(fn));
  2946. // write the header
  2947. if( fwrite(hdr,sizeof(unsigned),hn,fp) != hn )
  2948. {
  2949. rc = cmCtxRtCondition(&p->obj,cmSystemErrorRC,"Vector array file header write failed in '%s'.",cmStringNullGuard(fn));
  2950. goto errLabel;
  2951. }
  2952. // write each vector element
  2953. for(ep=p->bp,i=0; ep!=NULL; ep=ep->link,++i)
  2954. {
  2955. // write the count of data values in the vector
  2956. if( fwrite(&ep->n,sizeof(ep->n),1,fp) != 1 )
  2957. {
  2958. rc = cmCtxRtCondition(&p->obj,cmSystemErrorRC,"Vector array file write failed on element header %i in '%s'.",i,cmStringNullGuard(fn));
  2959. goto errLabel;
  2960. }
  2961. // write the vector
  2962. if(fwrite(ep->u.v,p->typeByteCnt,ep->n,fp) != ep->n )
  2963. {
  2964. rc = cmCtxRtCondition(&p->obj,cmSystemErrorRC,"Vector array file write failed on data vector %i in '%s'.",i,cmStringNullGuard(fn));
  2965. goto errLabel;
  2966. }
  2967. }
  2968. errLabel:
  2969. if( fp != NULL )
  2970. fclose(fp);
  2971. return rc;
  2972. }
  2973. cmRC_t cmVectArrayPrint( cmVectArray_t* p, cmRpt_t* rpt )
  2974. {
  2975. cmRC_t rc = cmOkRC;
  2976. cmVectArrayVect_t* rp = p->bp;
  2977. for(; rp!=NULL; rp=rp->link)
  2978. {
  2979. switch( p->flags & kVaMask )
  2980. {
  2981. case kFloatVaFl:
  2982. cmVOF_Print(rpt,1,rp->n,rp->u.fV);
  2983. break;
  2984. case kDoubleVaFl:
  2985. cmVOD_Print(rpt,1,rp->n,rp->u.dV);
  2986. break;
  2987. case kIntVaFl:
  2988. cmVOI_Print(rpt,1,rp->n,rp->u.iV);
  2989. break;
  2990. case kUIntVaFl:
  2991. cmVOU_Print(rpt,1,rp->n,rp->u.uV);
  2992. break;
  2993. default:
  2994. rc = cmCtxRtCondition(&p->obj,cmInvalidArgRC,"The vector array value type flag was not recognized.");
  2995. break;
  2996. }
  2997. }
  2998. return rc;
  2999. }
  3000. unsigned cmVectArrayForEachS( cmVectArray_t* p, unsigned idx, unsigned cnt, cmVectArrayForEachFuncS_t func, void* arg )
  3001. {
  3002. cmVectArrayVect_t* ep = p->bp;
  3003. unsigned i = 0;
  3004. unsigned n = 0;
  3005. // for each sub-array
  3006. for(; ep!=NULL && n<cnt; ep=ep->link )
  3007. {
  3008. // if the cur sub-array is in the range of idx:idx+cnt
  3009. if( i <= idx && idx < i + ep->n )
  3010. {
  3011. unsigned j = idx - i; // starting idx into cur sub-array
  3012. assert(j<ep->n);
  3013. unsigned m = cmMin(ep->n - j,cnt-n); // cnt of ele's to send from cur sub-array
  3014. // do callback
  3015. if( func(arg, idx, ep->u.sV + j, m ) != cmOkRC )
  3016. break;
  3017. idx += m;
  3018. n += m;
  3019. }
  3020. i += ep->n;
  3021. }
  3022. return n;
  3023. }
  3024. cmRC_t _cmVectArrayWriteMatrix( cmCtx* ctx, const char* fn, unsigned flags, const void* m, unsigned rn, unsigned cn )
  3025. {
  3026. cmRC_t rc = cmOkRC;
  3027. cmVectArray_t* p;
  3028. const char* b = (const char*)m;
  3029. unsigned tbc = _cmVectArrayTypeByteCnt( NULL, flags );
  3030. unsigned ri = 0;
  3031. char* vv = cmMemAlloc(char,cn*tbc);
  3032. if((p = cmVectArrayAlloc(ctx,flags)) == NULL )
  3033. return cmCtxRtCondition(&ctx->obj,cmSubSysFailRC,"Unable to allocate a cmVectArray_t in %s().",__FUNCTION__);
  3034. for(ri=0; ri<rn; ++ri)
  3035. {
  3036. // get ptr to first element in row 'ri' or m[]
  3037. const char* v = b + ri*tbc;
  3038. unsigned ci;
  3039. // for each column in m[ri,:]
  3040. for(ci=0; ci<cn; ++ci)
  3041. memcpy(vv + ci*tbc, v + ci*rn*tbc, tbc );
  3042. // append the row to the VectArray
  3043. if((rc = cmVectArrayAppendV(p,v,cn)) != cmOkRC )
  3044. {
  3045. rc = cmCtxRtCondition(&p->obj,rc,"Vector append failed in %s().",__FUNCTION__);
  3046. goto errLabel;
  3047. }
  3048. }
  3049. if((rc = cmVectArrayWrite(p,fn)) != cmOkRC )
  3050. rc = cmCtxRtCondition(&p->obj,rc,"Vector array write failed in %s().",__FUNCTION__);
  3051. errLabel:
  3052. if((rc = cmVectArrayFree(&p)) != cmOkRC )
  3053. rc = cmCtxRtCondition(&ctx->obj,rc,"Vector array free failed in %s().",__FUNCTION__);
  3054. cmMemFree(vv);
  3055. return rc;
  3056. }
  3057. cmRC_t cmVectArrayWriteVectorV( cmCtx* ctx, const char* fn, const void* v, unsigned vn, unsigned flags )
  3058. { return _cmVectArrayWriteMatrix( ctx, fn, flags, v, 1, vn ); }
  3059. cmRC_t cmVectArrayWriteVectorS( cmCtx* ctx, const char* fn, const cmSample_t* v, unsigned vn )
  3060. { return _cmVectArrayWriteMatrix( ctx, fn, kSampleVaFl, v, 1, vn ); }
  3061. cmRC_t cmVectArrayWriteVectorR( cmCtx* ctx, const char* fn, const cmReal_t* v, unsigned vn )
  3062. { return _cmVectArrayWriteMatrix( ctx, fn, kRealVaFl, v, 1, vn ); }
  3063. cmRC_t cmVectArrayWriteVectorD( cmCtx* ctx, const char* fn, const double* v, unsigned vn )
  3064. { return _cmVectArrayWriteMatrix( ctx, fn, kDoubleVaFl, v, 1, vn ); }
  3065. cmRC_t cmVectArrayWriteVectorF( cmCtx* ctx, const char* fn, const float* v, unsigned vn )
  3066. { return _cmVectArrayWriteMatrix( ctx, fn, kFloatVaFl, v, 1, vn ); }
  3067. cmRC_t cmVectArrayWriteVectorI( cmCtx* ctx, const char* fn, const int* v, unsigned vn )
  3068. { return _cmVectArrayWriteMatrix( ctx, fn, kIntVaFl, v, 1, vn ); }
  3069. cmRC_t cmVectArrayWriteVectorU( cmCtx* ctx, const char* fn, const unsigned* v, unsigned vn )
  3070. { return _cmVectArrayWriteMatrix( ctx, fn, kUIntVaFl, v, 1, vn ); }
  3071. cmRC_t cmVectArrayWriteMatrixV( cmCtx* ctx, const char* fn, const void* v, unsigned rn, unsigned cn, unsigned flags )
  3072. { return _cmVectArrayWriteMatrix( ctx, fn, flags, v, rn, cn); }
  3073. cmRC_t cmVectArrayWriteMatrixS( cmCtx* ctx, const char* fn, const cmSample_t* v, unsigned rn, unsigned cn )
  3074. { return _cmVectArrayWriteMatrix( ctx, fn, kSampleVaFl, v, rn, cn); }
  3075. cmRC_t cmVectArrayWriteMatrixR( cmCtx* ctx, const char* fn, const cmReal_t* v, unsigned rn, unsigned cn )
  3076. { return _cmVectArrayWriteMatrix( ctx, fn, kRealVaFl, v, rn, cn); }
  3077. cmRC_t cmVectArrayWriteMatrixD( cmCtx* ctx, const char* fn, const double* v, unsigned rn, unsigned cn )
  3078. { return _cmVectArrayWriteMatrix( ctx, fn, kDoubleVaFl, v, rn, cn); }
  3079. cmRC_t cmVectArrayWriteMatrixF( cmCtx* ctx, const char* fn, const float* v, unsigned rn, unsigned cn )
  3080. { return _cmVectArrayWriteMatrix( ctx, fn, kFloatVaFl, v, rn, cn); }
  3081. cmRC_t cmVectArrayWriteMatrixI( cmCtx* ctx, const char* fn, const int* v, unsigned rn, unsigned cn )
  3082. { return _cmVectArrayWriteMatrix( ctx, fn, kIntVaFl, v, rn, cn); }
  3083. cmRC_t cmVectArrayWriteMatrixU( cmCtx* ctx, const char* fn, const unsigned* v, unsigned rn, unsigned cn )
  3084. { return _cmVectArrayWriteMatrix( ctx, fn, kUIntVaFl, v, rn, cn); }
  3085. // Fill v[(*vnRef)*tbc] with the data from the current row of p.
  3086. // Return the count of elements copied to v[] in *vnRef.
  3087. cmRC_t _cmVectArrayGetV( cmVectArray_t* p, void* v, unsigned* vnRef, unsigned tbc )
  3088. {
  3089. assert( tbc == p->typeByteCnt );
  3090. if( cmVectArrayIsEOL(p) )
  3091. return cmCtxRtCondition(&p->obj,cmSubSysFailRC,"%s failed because the state is EOL.",__FUNCTION__);
  3092. unsigned n = cmMin((*vnRef)*tbc, p->cur->n * p->typeByteCnt );
  3093. memcpy(v, p->cur->u.v, n );
  3094. *vnRef = n/tbc;
  3095. return cmOkRC;
  3096. }
  3097. cmRC_t _cmVectArrayReadMatrixV( cmCtx* ctx, const char* fn, void** mRef, unsigned* rnRef, unsigned* cnRef )
  3098. {
  3099. assert( mRef != NULL );
  3100. assert( cnRef != NULL );
  3101. assert( rnRef != NULL );
  3102. *mRef = NULL;
  3103. *cnRef = 0;
  3104. *rnRef = 0;
  3105. cmRC_t rc = cmOkRC;
  3106. cmVectArray_t* va;
  3107. if((va = cmVectArrayAllocFromFile(ctx, fn )) == NULL )
  3108. rc = cmCtxRtCondition(&ctx->obj,cmSubSysFailRC,"Unable to read the vectarray from the file '%s'.", cmStringNullGuard(fn));
  3109. else
  3110. {
  3111. unsigned rn = cmVectArrayCount(va); // count of rows
  3112. unsigned cn = cmVectArrayMaxRowCount(va); // max count of ele's among all rows
  3113. char* m = cmMemAllocZ(char,va->typeByteCnt*rn*cn); // allocate the matrix
  3114. unsigned ci = 0;
  3115. cmVectArrayRewind(va);
  3116. // read each vector into a column of m[]
  3117. for(; !cmVectArrayIsEOL(va); ++ci)
  3118. {
  3119. unsigned n = cmVectArrayEleCount(va);
  3120. assert( m+(ci*rn+n)*va->typeByteCnt <= m + rn*cn*va->typeByteCnt );
  3121. if( _cmVectArrayGetV(va, m + ci*rn*va->typeByteCnt, &n, va->typeByteCnt) != cmOkRC )
  3122. goto errLabel;
  3123. cmVectArrayAdvance(va,1);
  3124. }
  3125. *mRef = m;
  3126. *cnRef = cn;
  3127. *rnRef = rn;
  3128. }
  3129. errLabel:
  3130. if( va != NULL )
  3131. cmVectArrayFree(&va);
  3132. return rc;
  3133. }
  3134. cmRC_t cmVectArrayReadMatrixV( cmCtx* ctx, const char* fn, void** mRef, unsigned* rnRef, unsigned* cnRef )
  3135. { return _cmVectArrayReadMatrixV(ctx, fn, mRef, rnRef, cnRef ); }
  3136. cmRC_t cmVectArrayReadMatrixS( cmCtx* ctx, const char* fn, cmSample_t** mRef, unsigned* rnRef, unsigned* cnRef )
  3137. { return _cmVectArrayReadMatrixV(ctx, fn, (void**)mRef, rnRef, cnRef ); }
  3138. cmRC_t cmVectArrayReadMatrixR( cmCtx* ctx, const char* fn, cmReal_t** mRef, unsigned* rnRef, unsigned* cnRef )
  3139. { return _cmVectArrayReadMatrixV(ctx, fn, (void**)mRef, rnRef, cnRef ); }
  3140. cmRC_t cmVectArrayReadMatrixD( cmCtx* ctx, const char* fn, double** mRef, unsigned* rnRef, unsigned* cnRef )
  3141. { return _cmVectArrayReadMatrixV(ctx, fn, (void**)mRef, rnRef, cnRef ); }
  3142. cmRC_t cmVectArrayReadMatrixF( cmCtx* ctx, const char* fn, float** mRef, unsigned* rnRef, unsigned* cnRef )
  3143. { return _cmVectArrayReadMatrixV(ctx, fn, (void**)mRef, rnRef, cnRef ); }
  3144. cmRC_t cmVectArrayReadMatrixI( cmCtx* ctx, const char* fn, int** mRef, unsigned* rnRef, unsigned* cnRef )
  3145. { return _cmVectArrayReadMatrixV(ctx, fn, (void**)mRef, rnRef, cnRef ); }
  3146. cmRC_t cmVectArrayReadMatrixU( cmCtx* ctx, const char* fn, unsigned** mRef, unsigned* rnRef, unsigned* cnRef )
  3147. { return _cmVectArrayReadMatrixV(ctx, fn, (void**)mRef, rnRef, cnRef ); }
  3148. cmRC_t cmVectArrayForEachTextFuncS( void* arg, unsigned idx, const cmSample_t* xV, unsigned xN )
  3149. {
  3150. assert(0);
  3151. return cmOkRC;
  3152. }
  3153. cmRC_t cmVectArrayRewind( cmVectArray_t* p )
  3154. {
  3155. p->cur = p->bp;
  3156. return cmOkRC;
  3157. }
  3158. cmRC_t cmVectArrayAdvance( cmVectArray_t* p, unsigned n )
  3159. {
  3160. unsigned i;
  3161. for(i=0; i<n; ++i)
  3162. {
  3163. if( p->cur == NULL )
  3164. break;
  3165. p->cur = p->cur->link;
  3166. }
  3167. return cmOkRC;
  3168. }
  3169. bool cmVectArrayIsEOL( const cmVectArray_t* p )
  3170. { return p->cur == NULL; }
  3171. unsigned cmVectArrayEleCount( const cmVectArray_t* p )
  3172. {
  3173. if( p->cur == NULL )
  3174. return 0;
  3175. return p->cur->n;
  3176. }
  3177. cmRC_t cmVectArrayGetV( cmVectArray_t* p, void* v, unsigned* vnRef )
  3178. { return _cmVectArrayGetV(p,v,vnRef,_cmVectArrayTypeByteCnt(p,p->flags)); }
  3179. cmRC_t cmVectArrayGetS( cmVectArray_t* p, cmSample_t* v, unsigned* vnRef )
  3180. {
  3181. assert( cmIsFlag(p->flags,kSampleVaFl) );
  3182. return _cmVectArrayGetV(p,v,vnRef,sizeof(cmSample_t));
  3183. }
  3184. cmRC_t cmVectArrayGetR( cmVectArray_t* p, cmReal_t* v, unsigned* vnRef )
  3185. {
  3186. assert( cmIsFlag(p->flags,kRealVaFl) );
  3187. return _cmVectArrayGetV(p,v,vnRef,sizeof(cmReal_t));
  3188. }
  3189. cmRC_t cmVectArrayGetD( cmVectArray_t* p, double* v, unsigned* vnRef )
  3190. {
  3191. assert( cmIsFlag(p->flags,kDoubleVaFl) );
  3192. return _cmVectArrayGetV(p,v,vnRef,sizeof(double));
  3193. }
  3194. cmRC_t cmVectArrayGetF( cmVectArray_t* p, float* v, unsigned* vnRef )
  3195. {
  3196. assert( cmIsFlag(p->flags,kFloatVaFl) );
  3197. return _cmVectArrayGetV(p,v,vnRef,sizeof(float));
  3198. }
  3199. cmRC_t cmVectArrayGetI( cmVectArray_t* p, int* v, unsigned* vnRef )
  3200. {
  3201. assert( cmIsFlag(p->flags,kIntVaFl) );
  3202. return _cmVectArrayGetV(p,v,vnRef,sizeof(int));
  3203. }
  3204. cmRC_t cmVectArrayGetU( cmVectArray_t* p, unsigned* v, unsigned* vnRef )
  3205. {
  3206. assert( cmIsFlag(p->flags,kUIntVaFl) );
  3207. return _cmVectArrayGetV(p,v,vnRef,sizeof(unsigned));
  3208. }
  3209. cmRC_t _cmVectArrayMatrixIsEqual( cmCtx* ctx, const char* fn, const void* mm, unsigned rn, unsigned cn, unsigned flags, bool* resultFlRef )
  3210. {
  3211. assert( resultFlRef != NULL );
  3212. cmRC_t rc = cmOkRC;
  3213. cmVectArray_t* p = NULL;
  3214. const char* m = (const char*)mm;
  3215. unsigned tbc = _cmVectArrayTypeByteCnt(NULL,flags);
  3216. unsigned ri = 0;
  3217. char* vv = cmMemAlloc(char,cn*tbc);
  3218. *resultFlRef = false;
  3219. // read the vector array
  3220. if((p = cmVectArrayAllocFromFile(ctx, fn )) == NULL)
  3221. {
  3222. rc = cmCtxRtCondition(&ctx->obj,cmSubSysFailRC,"Unable to read the VectArray from the file '%s'.", cmStringNullGuard(fn));
  3223. goto errLabel;
  3224. }
  3225. // verify that the matrix type matches the vector array type
  3226. if( (p->flags & kVaMask) != (flags & kVaMask) )
  3227. {
  3228. rc = cmCtxRtCondition(&ctx->obj,cmInvalidArgRC,"Invalid type conversion in '%s'.",__FUNCTION__);
  3229. goto errLabel;
  3230. }
  3231. // the row count of the VectArray and m[] must be the same
  3232. if( cmVectArrayCount(p) != rn )
  3233. {
  3234. *resultFlRef = false;
  3235. goto errLabel;
  3236. }
  3237. // for each row in VectArray
  3238. for(; !cmVectArrayIsEOL(p); ++ri )
  3239. {
  3240. unsigned vn = cmVectArrayEleCount(p);
  3241. char v[ vn*p->typeByteCnt ];
  3242. unsigned ci;
  3243. // get the current row from the VectArray into v[vn]
  3244. if( _cmVectArrayGetV(p,v,&vn,p->typeByteCnt) != cmOkRC )
  3245. goto errLabel;
  3246. // if the size of the current row does not match the row element count of the matrix
  3247. if( vn != cn )
  3248. goto errLabel;
  3249. for(ci=0; ci<cn; ++ci)
  3250. memcpy(vv + ci*tbc, m + (ri*tbc) + (ci*rn*tbc), tbc );
  3251. // the current row does not match the matrix column vector
  3252. if( memcmp(v, vv, vn*p->typeByteCnt ) != 0 )
  3253. goto errLabel;
  3254. cmVectArrayAdvance(p,1);
  3255. }
  3256. *resultFlRef = true;
  3257. errLabel:
  3258. if( p != NULL )
  3259. cmVectArrayFree(&p);
  3260. cmMemFree(vv);
  3261. return rc;
  3262. }
  3263. cmRC_t cmVectArrayMatrixIsEqualV( cmCtx* ctx, const char* fn, const void* m, unsigned rn, unsigned cn, bool* resultFlRef, unsigned flags )
  3264. { return _cmVectArrayMatrixIsEqual(ctx, fn, m, rn, cn, flags, resultFlRef); }
  3265. cmRC_t cmVectArrayMatrixIsEqualS( cmCtx* ctx, const char* fn, const cmSample_t* m, unsigned rn, unsigned cn, bool* resultFlRef )
  3266. { return _cmVectArrayMatrixIsEqual(ctx, fn, m, rn, cn, kSampleVaFl, resultFlRef ); }
  3267. cmRC_t cmVectArrayMatrixIsEqualR( cmCtx* ctx, const char* fn, const cmReal_t* m, unsigned rn, unsigned cn, bool* resultFlRef )
  3268. { return _cmVectArrayMatrixIsEqual(ctx, fn, m, rn, cn, kRealVaFl, resultFlRef ); }
  3269. cmRC_t cmVectArrayMatrixIsEqualD( cmCtx* ctx, const char* fn, const double* m, unsigned rn, unsigned cn, bool* resultFlRef )
  3270. { return _cmVectArrayMatrixIsEqual(ctx, fn, m, rn, cn, kDoubleVaFl, resultFlRef ); }
  3271. cmRC_t cmVectArrayMatrixIsEqualF( cmCtx* ctx, const char* fn, const float* m, unsigned rn, unsigned cn, bool* resultFlRef )
  3272. { return _cmVectArrayMatrixIsEqual(ctx, fn, m, rn, cn, kFloatVaFl, resultFlRef ); }
  3273. cmRC_t cmVectArrayMatrixIsEqualI( cmCtx* ctx, const char* fn, const int* m, unsigned rn, unsigned cn, bool* resultFlRef )
  3274. { return _cmVectArrayMatrixIsEqual(ctx, fn, m, rn, cn, kIntVaFl, resultFlRef ); }
  3275. cmRC_t cmVectArrayMatrixIsEqualU( cmCtx* ctx, const char* fn, const unsigned* m, unsigned rn, unsigned cn, bool* resultFlRef )
  3276. { return _cmVectArrayMatrixIsEqual(ctx, fn, m, rn, cn, kUIntVaFl, resultFlRef ); }
  3277. unsigned cmVectArrayVectEleCount( cmVectArray_t* p, unsigned groupIdx, unsigned groupCnt )
  3278. {
  3279. unsigned n = 0;
  3280. cmVectArrayVect_t* pos = p->cur;
  3281. if( cmVectArrayRewind(p) != cmOkRC )
  3282. goto errLabel;
  3283. if( cmVectArrayAdvance(p,groupIdx) != cmOkRC )
  3284. goto errLabel;
  3285. while( !cmVectArrayIsEOL(p) )
  3286. {
  3287. n += cmVectArrayEleCount(p);
  3288. if(cmVectArrayAdvance(p,groupCnt) != cmOkRC )
  3289. goto errLabel;
  3290. }
  3291. errLabel:
  3292. p->cur = pos;
  3293. return n;
  3294. }
  3295. cmRC_t cmVectArrayFormVectF( cmVectArray_t* p, unsigned groupIdx, unsigned groupCnt, float** vRef, unsigned* vnRef )
  3296. {
  3297. cmRC_t rc = cmOkRC;
  3298. *vRef = NULL;
  3299. *vnRef = 0;
  3300. unsigned N = cmVectArrayVectEleCount(p,groupIdx,groupCnt);
  3301. if( N == 0 )
  3302. return rc;
  3303. float* v = cmMemAllocZ(float,N);
  3304. unsigned i = 0;
  3305. cmVectArrayVect_t* pos = p->cur;
  3306. if( cmVectArrayRewind(p) != cmOkRC )
  3307. goto errLabel;
  3308. if( cmVectArrayAdvance(p,groupIdx) != cmOkRC )
  3309. goto errLabel;
  3310. while( !cmVectArrayIsEOL(p) )
  3311. {
  3312. unsigned n = cmVectArrayEleCount(p);
  3313. assert(i+n <= N);
  3314. cmVectArrayGetF(p,v+i,&n);
  3315. i += n;
  3316. cmVectArrayAdvance(p,groupCnt);
  3317. }
  3318. *vRef = v;
  3319. *vnRef = i;
  3320. errLabel:
  3321. p->cur = pos;
  3322. return rc;
  3323. }
  3324. cmRC_t cmVectArrayFormVectColF( cmVectArray_t* p, unsigned groupIdx, unsigned groupCnt, unsigned colIdx, float** vRef, unsigned* vnRef )
  3325. {
  3326. cmRC_t rc = cmOkRC;
  3327. *vRef = NULL;
  3328. *vnRef = 0;
  3329. // assume there will be one output element for each group
  3330. unsigned N = cmVectArrayCount(p)/groupCnt + 1;
  3331. if( N == 0 )
  3332. return rc;
  3333. float* v = cmMemAllocZ(float,N);
  3334. unsigned i = 0;
  3335. cmVectArrayVect_t* pos = p->cur;
  3336. if( cmVectArrayRewind(p) != cmOkRC )
  3337. goto errLabel;
  3338. if( cmVectArrayAdvance(p,groupIdx) != cmOkRC )
  3339. goto errLabel;
  3340. while( i<N && !cmVectArrayIsEOL(p) )
  3341. {
  3342. unsigned tn = cmVectArrayEleCount(p);
  3343. float tv[tn];
  3344. // read the sub-vector
  3345. cmVectArrayGetF(p,tv,&tn);
  3346. // store the output value
  3347. if( colIdx < tn )
  3348. {
  3349. v[i] = tv[colIdx];
  3350. i += 1;
  3351. }
  3352. cmVectArrayAdvance(p,groupCnt);
  3353. }
  3354. *vRef = v;
  3355. *vnRef = i;
  3356. errLabel:
  3357. p->cur = pos;
  3358. return rc;
  3359. }
  3360. cmRC_t cmVectArrayFormVectColU( cmVectArray_t* p, unsigned groupIdx, unsigned groupCnt, unsigned colIdx, unsigned** vRef, unsigned* vnRef )
  3361. {
  3362. cmRC_t rc = cmOkRC;
  3363. *vRef = NULL;
  3364. *vnRef = 0;
  3365. // assume there will be one output element for each group
  3366. unsigned N = cmVectArrayCount(p)/groupCnt + 1;
  3367. if( N == 0 )
  3368. return rc;
  3369. unsigned* v = cmMemAllocZ(unsigned,N);
  3370. unsigned i = 0;
  3371. cmVectArrayVect_t* pos = p->cur;
  3372. if( cmVectArrayRewind(p) != cmOkRC )
  3373. goto errLabel;
  3374. if( cmVectArrayAdvance(p,groupIdx) != cmOkRC )
  3375. goto errLabel;
  3376. while( i<N && !cmVectArrayIsEOL(p) )
  3377. {
  3378. unsigned tn = cmVectArrayEleCount(p);
  3379. unsigned tv[tn];
  3380. // read the sub-vector
  3381. cmVectArrayGetU(p,tv,&tn);
  3382. assert( colIdx < tn );
  3383. // store the output value
  3384. if( colIdx < tn )
  3385. v[i++] = tv[colIdx];
  3386. cmVectArrayAdvance(p,groupCnt);
  3387. }
  3388. *vRef = v;
  3389. *vnRef = i;
  3390. errLabel:
  3391. p->cur = pos;
  3392. return rc;
  3393. }
  3394. cmRC_t cmVectArrayTest( cmCtx* ctx, const char* fn, bool genFl )
  3395. {
  3396. cmRC_t rc = cmOkRC;
  3397. cmVectArray_t* p = NULL;
  3398. if( fn == NULL || strlen(fn)==0 )
  3399. return cmCtxRtCondition(&p->obj,cmSubSysFailRC,"Invalid test output file name.");
  3400. if( genFl )
  3401. {
  3402. unsigned flags = kSampleVaFl;
  3403. cmSample_t v[] = { 0, 1, 2, 3, 4, 5 };
  3404. if( (p = cmVectArrayAlloc(ctx,flags)) == NULL )
  3405. return cmCtxRtCondition(&p->obj,cmSubSysFailRC,"The vectory array object allocation failed.");
  3406. if( cmVectArrayAppendS(p,v,1) != cmOkRC )
  3407. {
  3408. rc = cmCtxRtCondition(&p->obj,cmSubSysFailRC,"Vector append 1 failed.");
  3409. goto errLabel;
  3410. }
  3411. if( cmVectArrayAppendS(p,v+1,2) != cmOkRC )
  3412. {
  3413. rc = cmCtxRtCondition(&p->obj,cmSubSysFailRC,"Vector append 2 failed.");
  3414. goto errLabel;
  3415. }
  3416. if( cmVectArrayAppendS(p,v+3,3) != cmOkRC )
  3417. {
  3418. rc = cmCtxRtCondition(&p->obj,cmSubSysFailRC,"Vector append 3 failed.");
  3419. goto errLabel;
  3420. }
  3421. if( cmVectArrayWrite(p,fn) != cmOkRC )
  3422. {
  3423. rc = cmCtxRtCondition(&p->obj,cmSubSysFailRC,"Vector array write failed.");
  3424. goto errLabel;
  3425. }
  3426. //cmVectArrayForEachS(p,0,cmVectArrayEleCount(p),cmVectArrayForEachTextFuncS,&ctx->printRpt);
  3427. //if( cmVectArrayFree(&p) != cmOkRC )
  3428. //{
  3429. // rc = cmCtxRtCondition(&p->obj,cmSubSysFailRC,"The vectory array release failed.");
  3430. // goto errLabel;
  3431. //}
  3432. }
  3433. else
  3434. {
  3435. if((p = cmVectArrayAllocFromFile(ctx, fn )) == NULL )
  3436. {
  3437. rc = cmCtxRtCondition(&p->obj,cmSubSysFailRC,"VectArray alloc from file failed.");
  3438. goto errLabel;
  3439. }
  3440. while(!cmVectArrayIsEOL(p))
  3441. {
  3442. unsigned n = cmVectArrayEleCount(p);
  3443. cmSample_t v[n];
  3444. if( cmVectArrayGetS(p,v,&n) != cmOkRC )
  3445. {
  3446. rc = cmCtxRtCondition(&p->obj,cmSubSysFailRC,"VectArrayGetS() failed.");
  3447. goto errLabel;
  3448. }
  3449. //cmVOS_PrintL("v:",NULL,1,n,v);
  3450. cmVectArrayAdvance(p,1);
  3451. }
  3452. // Test matrix reading
  3453. cmSample_t* m;
  3454. unsigned rn,cn;
  3455. if( cmVectArrayReadMatrixS(ctx, fn, &m, &rn, &cn ) != cmOkRC )
  3456. goto errLabel;
  3457. else
  3458. {
  3459. //cmVOS_PrintL("v:",NULL,rn,cn,m);
  3460. cmMemFree(m);
  3461. }
  3462. }
  3463. errLabel:
  3464. if( cmVectArrayFree(&p) != cmOkRC )
  3465. rc = cmCtxRtCondition(&p->obj,cmSubSysFailRC,"The vector array release failed.");
  3466. return rc;
  3467. }
  3468. //-----------------------------------------------------------------------------------------------------------------------
  3469. cmWhFilt* cmWhFiltAlloc( cmCtx* c, cmWhFilt* p, unsigned binCnt, cmReal_t binHz, cmReal_t coeff, cmReal_t maxHz )
  3470. {
  3471. cmWhFilt* op = cmObjAlloc(cmWhFilt,c,p);
  3472. if( binCnt > 0 )
  3473. if( cmWhFiltInit(op,binCnt,binHz,coeff,maxHz) != cmOkRC )
  3474. cmWhFiltFree(&op);
  3475. return op;
  3476. }
  3477. cmRC_t cmWhFiltFree( cmWhFilt** pp )
  3478. {
  3479. cmRC_t rc = cmOkRC;
  3480. if( pp==NULL || *pp==NULL )
  3481. return rc;
  3482. cmWhFilt* p = *pp;
  3483. if((rc = cmWhFiltFinal(p)) != cmOkRC )
  3484. return rc;
  3485. cmMemFree(p->whM);
  3486. cmMemFree(p->whiV);
  3487. cmMemFree(p->iV);
  3488. cmObjFree(pp);
  3489. return rc;
  3490. }
  3491. cmRC_t cmWhFiltInit( cmWhFilt* p, unsigned binCnt, cmReal_t binHz, cmReal_t coeff, cmReal_t maxHz )
  3492. {
  3493. cmRC_t rc;
  3494. if((rc = cmWhFiltFinal(p)) != cmOkRC )
  3495. return rc;
  3496. p->binCnt = binCnt;
  3497. p->binHz = binHz;
  3498. p->bandCnt = maxHz == 0 ? 34 : ceil(log10(maxHz/229.0 + 1) * 21.4 - 1)-1;
  3499. if( p->bandCnt <= 0 )
  3500. return cmCtxRtCondition(&p->obj, cmInvalidArgRC, "Max. Hz too low to form any frequency bands.");
  3501. cmReal_t flV[ p->bandCnt ];
  3502. cmReal_t fcV[ p->bandCnt ];
  3503. cmReal_t fhV[ p->bandCnt ];
  3504. int i;
  3505. for(i=0; i<p->bandCnt; ++i)
  3506. {
  3507. fcV[i] = 229.0 * (pow(10.0,(i+2)/21.4) - 1.0);
  3508. flV[i] = i==0 ? 0 : fcV[i-1];
  3509. }
  3510. for(i=0; i<p->bandCnt-1; ++i)
  3511. fhV[i] = fcV[i+1];
  3512. fhV[p->bandCnt-1] = fcV[p->bandCnt-1] + (fcV[p->bandCnt-1] - fcV[p->bandCnt-2]);
  3513. //cmVOR_PrintL("flV",NULL,1,p->bandCnt,flV);
  3514. //cmVOR_PrintL("fcV",NULL,1,p->bandCnt,fcV);
  3515. //cmVOR_PrintL("fhV",NULL,1,p->bandCnt,fhV);
  3516. cmReal_t* tM = cmMemAlloc(cmReal_t,p->bandCnt * p->binCnt);
  3517. p->whM = cmMemResizeZ(cmReal_t,p->whM,p->binCnt * p->bandCnt);
  3518. p->iV = cmMemResizeZ(cmReal_t,p->iV,p->binCnt);
  3519. // generate the bin index values
  3520. for(i=0; i<p->binCnt; ++i)
  3521. p->iV[i] = i;
  3522. cmReal_t stSpread = 0; // set stSpread to 0 to use flV/fhV[]
  3523. cmVOR_TriangleMask(tM, p->bandCnt, p->binCnt, fcV, p->binHz, stSpread, flV, fhV );
  3524. cmVOR_Transpose(p->whM, tM, p->bandCnt, p->binCnt );
  3525. cmMemFree(tM);
  3526. //cmVOR_PrintL("whM",NULL,p->bandCnt,p->binCnt,p->whM);
  3527. //cmVectArrayWriteMatrixR(p->obj.ctx, "/home/kevin/temp/frqtrk/whM.va", p->whM, p->binCnt, p->bandCnt );
  3528. unsigned whiN = p->bandCnt+2;
  3529. p->whiV = cmMemResizeZ(cmReal_t,p->whiV,whiN);
  3530. for(i=0; i<whiN; ++i)
  3531. {
  3532. if( i == 0 )
  3533. p->whiV[i] = 0;
  3534. else
  3535. if( i == whiN-1 )
  3536. p->whiV[i] = fhV[p->bandCnt-1]/binHz;
  3537. else
  3538. p->whiV[i] = fcV[i-1]/binHz;
  3539. }
  3540. //cmVOR_PrintL("whiV",NULL,1,whiN,p->whiV);
  3541. //cmVectArrayWriteMatrixR(p->obj.ctx, "/home/kevin/temp/frqtrk/whiV.va", p->whiV, whiN, 1 );
  3542. return rc;
  3543. }
  3544. cmRC_t cmWhFiltFinal( cmWhFilt* p )
  3545. { return cmOkRC; }
  3546. cmRC_t cmWhFiltExec( cmWhFilt* p, const cmReal_t* xV, cmReal_t* yV, unsigned xyN )
  3547. {
  3548. assert( xyN == p->binCnt);
  3549. cmRC_t rc = cmOkRC;
  3550. unsigned whiN = p->bandCnt + 2;
  3551. unsigned mbi = cmMin(xyN, floor(p->whiV[whiN-1]));
  3552. // calculate the level in each band to form a composite filter
  3553. cmReal_t y0V[ whiN ];
  3554. cmReal_t* b0V = y0V + 1;
  3555. cmVOR_MultVVM(b0V, p->bandCnt, xV, p->binCnt, p->whM );
  3556. //cmVOR_PrintL("b0V",NULL,1,p->bandCnt,b0V);
  3557. // BEWARE: zeros in b0V will generate Inf's when sent
  3558. // through the cmVOR_PowVS() function.
  3559. int i;
  3560. for(i=0; i<p->bandCnt; ++i)
  3561. if( b0V[i] < 0.000001 )
  3562. b0V[i] = 0.000001;
  3563. // apply a non-linear expansion function to each band
  3564. cmVOR_PowVS(b0V,p->bandCnt,p->coeff-1);
  3565. //cmVOR_PrintL("b0V",NULL,1,p->bandCnt,b0V);
  3566. // add edge values to the filter
  3567. y0V[0] = b0V[0];
  3568. y0V[whiN-1] = b0V[p->bandCnt-1];
  3569. //cmVOR_PrintL("y0V",NULL,1,whiN,y0V);
  3570. cmVOR_Interp1(yV,p->iV,p->binCnt,p->whiV,y0V,whiN);
  3571. cmVOR_Fill(yV+mbi,xyN-mbi,1.0);
  3572. //cmVOR_PrintL("yV",NULL,1,p->binCnt,yV);
  3573. cmVOR_MultVV(yV,xyN,xV);
  3574. return rc;
  3575. }
  3576. //-----------------------------------------------------------------------------------------------------------------------
  3577. cmFrqTrk* cmFrqTrkAlloc( cmCtx* c, cmFrqTrk* p, const cmFrqTrkArgs_t* a )
  3578. {
  3579. cmFrqTrk* op = cmObjAlloc(cmFrqTrk,c,p);
  3580. op->logVa = cmVectArrayAlloc(c,kRealVaFl);
  3581. op->levelVa = cmVectArrayAlloc(c,kRealVaFl);
  3582. op->specVa = cmVectArrayAlloc(c,kRealVaFl);
  3583. op->attenVa = cmVectArrayAlloc(c,kRealVaFl);
  3584. op->wf = cmWhFiltAlloc(c,NULL,0,0,0,0);
  3585. if( a != NULL )
  3586. if( cmFrqTrkInit(op,a) != cmOkRC )
  3587. cmFrqTrkFree(&op);
  3588. return op;
  3589. }
  3590. cmRC_t cmFrqTrkFree( cmFrqTrk** pp )
  3591. {
  3592. cmRC_t rc = cmOkRC;
  3593. if( pp==NULL || *pp==NULL )
  3594. return rc;
  3595. cmFrqTrk* p = *pp;
  3596. if((rc = cmFrqTrkFinal(p)) != cmOkRC )
  3597. return rc;
  3598. unsigned i;
  3599. for(i=0; i<p->a.chCnt; ++i)
  3600. {
  3601. cmMemFree(p->ch[i].dbV);
  3602. cmMemFree(p->ch[i].hzV);
  3603. }
  3604. cmMemFree(p->ch);
  3605. cmMemFree(p->dbM);
  3606. cmMemFree(p->pkiV);
  3607. cmMemFree(p->dbV);
  3608. cmMemFree(p->aV);
  3609. cmVectArrayFree(&p->logVa);
  3610. cmVectArrayFree(&p->levelVa);
  3611. cmVectArrayFree(&p->specVa);
  3612. cmVectArrayFree(&p->attenVa);
  3613. cmWhFiltFree(&p->wf);
  3614. cmMemFree(p->logFn);
  3615. cmMemFree(p->levelFn);
  3616. cmMemFree(p->specFn);
  3617. cmMemFree(p->attenFn);
  3618. cmObjFree(pp);
  3619. return rc;
  3620. }
  3621. cmRC_t cmFrqTrkInit( cmFrqTrk* p, const cmFrqTrkArgs_t* a )
  3622. {
  3623. cmRC_t rc;
  3624. if((rc = cmFrqTrkFinal(p)) != cmOkRC )
  3625. return rc;
  3626. p->a = *a;
  3627. p->ch = cmMemResizeZ(cmFrqTrkCh_t,p->ch,a->chCnt );
  3628. p->hN = cmMax(1,a->wndSecs * a->srate / a->hopSmpCnt );
  3629. p->sN = 4*p->hN;
  3630. p->binHz = a->srate / ((p->a.binCnt-1)*2);
  3631. p->bN = cmMin( p->a.binCnt, ceil(p->a.pkMaxHz / p->binHz ));
  3632. p->dbM = cmMemResizeZ(cmReal_t,p->dbM,p->hN*p->bN);
  3633. p->hi = 0;
  3634. p->fN = 0;
  3635. p->dbV = cmMemResizeZ(cmReal_t,p->dbV,p->bN);
  3636. p->pkiV = cmMemResizeZ(unsigned,p->pkiV,p->bN);
  3637. p->deadN_max = a->maxTrkDeadSec * a->srate / a->hopSmpCnt;
  3638. p->minTrkN = a->minTrkSec * a->srate / a->hopSmpCnt;
  3639. p->nextTrkId = 1;
  3640. p->aV = cmMemResizeZ(cmReal_t,p->aV,p->a.binCnt);
  3641. p->attenDlyPhsMax = cmMax(3,a->attenDlySec * a->srate / a->hopSmpCnt );
  3642. p->attenPhsMax = cmMax(3,a->attenAtkSec * a->srate / a->hopSmpCnt );
  3643. if( a->logFn != NULL )
  3644. p->logFn = cmMemResizeStr(p->logFn,a->logFn);
  3645. if( a->levelFn != NULL )
  3646. p->levelFn = cmMemResizeStr(p->levelFn,a->levelFn);
  3647. if( a->specFn != NULL )
  3648. p->specFn = cmMemResizeStr(p->specFn,a->specFn);
  3649. if( a->attenFn != NULL )
  3650. p->attenFn = cmMemResizeStr(p->attenFn,a->attenFn);
  3651. if(cmWhFiltInit(p->wf,p->bN,p->binHz,p->a.whFiltCoeff,p->a.pkMaxHz) != cmOkRC )
  3652. cmCtxRtCondition(&p->obj, cmSubSysFailRC, "Whitening filter intitialization failed.");
  3653. unsigned i;
  3654. for(i=0; i<p->a.chCnt; ++i)
  3655. {
  3656. p->ch[i].dbV = cmMemResizeZ(cmReal_t,p->ch[i].dbV,p->sN);
  3657. p->ch[i].hzV = cmMemResizeZ(cmReal_t,p->ch[i].hzV,p->sN);
  3658. }
  3659. return rc;
  3660. }
  3661. cmRC_t cmFrqTrkFinal( cmFrqTrk* p )
  3662. {
  3663. cmRC_t rc = cmOkRC;
  3664. if( p->logFn != NULL )
  3665. cmVectArrayWrite(p->logVa,p->logFn);
  3666. if( p->levelFn != NULL )
  3667. cmVectArrayWrite(p->levelVa,p->levelFn);
  3668. if( p->specFn != NULL )
  3669. cmVectArrayWrite(p->specVa,p->specFn);
  3670. if( p->attenFn != NULL )
  3671. cmVectArrayWrite(p->attenVa,p->attenFn);
  3672. cmWhFiltFinal(p->wf);
  3673. return rc;
  3674. }
  3675. // Return an available channel record or NULL if all channel records are in use.
  3676. cmFrqTrkCh_t* _cmFrqTrkFindAvailCh( cmFrqTrk* p )
  3677. {
  3678. unsigned i;
  3679. for(i=0; i<p->a.chCnt; ++i)
  3680. if( p->ch[i].activeFl == false )
  3681. return p->ch + i;
  3682. return NULL;
  3683. }
  3684. // Estimate the peak frequency by parabolic interpolotion into hzV[p->bN]
  3685. void _cmFrqTrkMagnToHz( cmFrqTrk* p, const cmReal_t* dbV, unsigned* pkiV, unsigned pkN, cmReal_t* hzV )
  3686. {
  3687. unsigned i;
  3688. for(i=0; i<pkN; ++i)
  3689. if( pkiV[i] != cmInvalidIdx )
  3690. {
  3691. unsigned pki = pkiV[i];
  3692. cmReal_t y0 = pki>0 ? dbV[ pki-1 ] : dbV[pki];
  3693. cmReal_t y1 = dbV[ pki ];
  3694. cmReal_t y2 = pki<p->bN-1 ? dbV[ pki+1 ] : dbV[pki];
  3695. cmReal_t den = y0 - (2.*y1) + y2;
  3696. cmReal_t offs = den==0 ? 0 : 0.5 * ((y0 - y2) / den);
  3697. hzV[pki] = p->binHz * (pki+offs);
  3698. //if( hzV[pki] < 0 )
  3699. //{
  3700. // printf("%f : %f %f %f : %f %f\n",hzV[pki],y0,y1,y2,den,offs);
  3701. //}
  3702. }
  3703. }
  3704. unsigned _cmFrqTrkActiveChCount( cmFrqTrk* p )
  3705. {
  3706. unsigned n = 0;
  3707. unsigned i;
  3708. for(i=0; i<p->a.chCnt; ++i)
  3709. if( p->ch[i].activeFl )
  3710. ++n;
  3711. return n;
  3712. }
  3713. void _cmFrqTrkWriteLevel( cmFrqTrk* p, const cmReal_t* dbV, const cmReal_t* hzV, unsigned bN )
  3714. {
  3715. if( p->levelFn != NULL )
  3716. {
  3717. double maxHz = 5000.0;
  3718. unsigned maxBinIdx = cmMin(bN,maxHz / p->binHz);
  3719. unsigned vn = 3;
  3720. cmReal_t v[vn];
  3721. unsigned idx = cmVOR_MaxIndex(dbV,maxBinIdx,1);
  3722. v[0] = cmVOR_Mean(dbV,maxBinIdx);
  3723. v[1] = dbV[idx];
  3724. v[2] = hzV[idx];
  3725. cmVectArrayAppendR(p->levelVa,v,vn);
  3726. }
  3727. }
  3728. void _cmFrqTrkWriteLog( cmFrqTrk* p )
  3729. {
  3730. unsigned n;
  3731. cmReal_t* vb = NULL;
  3732. if( p->logFn == NULL )
  3733. return;
  3734. if((n = _cmFrqTrkActiveChCount(p)) > 0 )
  3735. {
  3736. unsigned i,j;
  3737. // sn = count of elements in the summary sub-vector
  3738. unsigned sn = 3;
  3739. // each active channel will emit 7 values
  3740. unsigned nn = 1 + n*7 + sn;
  3741. // allocate the row vector
  3742. vb = cmMemResize(cmReal_t,vb,nn);
  3743. // row format
  3744. // [ nn idV[n] hzV[n] ... hsV[n] smV[sn] ]
  3745. // n = (nn - (1 + sn)) / 7
  3746. *vb = nn; // the first element in the vector contains the length of the row
  3747. cmReal_t* v = vb + 1;
  3748. // setup the base pointer to each sub-vector
  3749. cmReal_t* idV = v + n * 0;
  3750. cmReal_t* hzV = v + n * 1;
  3751. cmReal_t* dbV = v + n * 2;
  3752. cmReal_t* stV = v + n * 3;
  3753. cmReal_t* dsV = v + n * 4;
  3754. cmReal_t* hsV = v + n * 5;
  3755. cmReal_t* agV = v + n * 6;
  3756. cmReal_t* smV = v + n * 7; // summary information
  3757. smV[0] = p->newTrkCnt;
  3758. smV[1] = p->curTrkCnt;
  3759. smV[2] = p->deadTrkCnt;
  3760. // for each active channel
  3761. for(i=0,j=0; i<p->a.chCnt; ++i)
  3762. if( p->ch[i].activeFl )
  3763. {
  3764. assert(j < n);
  3765. // elements of each sub-vector associated with a given
  3766. // index refer to the same track record - element i therefore
  3767. // refers to active track index i.
  3768. idV[j] = p->ch[i].id;
  3769. hzV[j] = p->ch[i].hz;
  3770. dbV[j] = p->ch[i].db;
  3771. stV[j] = p->ch[i].dN;
  3772. dsV[j] = p->ch[i].db_std;
  3773. hsV[j] = p->ch[i].hz_std;
  3774. agV[j] = p->ch[i].attenGain;
  3775. ++j;
  3776. }
  3777. cmVectArrayAppendR(p->logVa, vb, nn );
  3778. }
  3779. cmMemFree(vb);
  3780. }
  3781. void _cmFrqTrkPrintChs( const cmFrqTrk* p )
  3782. {
  3783. unsigned i;
  3784. for(i=0; i<p->a.chCnt; ++i)
  3785. {
  3786. cmFrqTrkCh_t* c = p->ch + i;
  3787. printf("%i : %i tN:%i hz:%f db:%f\n",i,c->activeFl,c->tN,c->hz,c->db);
  3788. }
  3789. }
  3790. // Used to sort the channels into descending dB order.
  3791. int _cmFrqTrkChCompare( const void* p0, const void* p1 )
  3792. { return ((cmFrqTrkCh_t*)p0)->db - ((cmFrqTrkCh_t*)p1)->db; }
  3793. // Return the index of the peak associated with pkiV[i] which best matches the tracker 'c'
  3794. // or cmInvalidIdx if no valid peaks were found.
  3795. // pkiV[ pkN ] holds the indexes into dbV[] and hzV[] which are peaks.
  3796. // Some elements of pkiV[] may be set to cmInvalidIdx if the associated peak has already
  3797. // been selected by another tracker.
  3798. unsigned _cmFrqTrkFindPeak( cmFrqTrk* p, const cmFrqTrkCh_t* c, const cmReal_t* dbV, const cmReal_t* hzV, unsigned* pkiV, unsigned pkN )
  3799. {
  3800. unsigned i,pki;
  3801. cmReal_t d_max = p->a.pkThreshDb;
  3802. unsigned d_idx = cmInvalidIdx;
  3803. cmReal_t hz_min = c->hz * pow(2,-p->a.stRange/12.0);
  3804. cmReal_t hz_max = c->hz * pow(2, p->a.stRange/12.0);
  3805. // find the peak with the most energy inside the frequency range hz_min to hz_max.
  3806. for(i=0; i<pkN; ++i)
  3807. if( ((pki = pkiV[i]) != cmInvalidIdx) && hz_min <= hzV[pki] && hzV[pki] <= hz_max && dbV[pki]>d_max )
  3808. {
  3809. d_max= dbV[pki];
  3810. d_idx = i;
  3811. }
  3812. return d_idx;
  3813. }
  3814. void _cmFrqTrkScoreChs( cmFrqTrk* p )
  3815. {
  3816. unsigned i;
  3817. for(i=0; i<p->a.chCnt; ++i)
  3818. if( p->ch[i].activeFl )
  3819. {
  3820. cmFrqTrkCh_t* c = p->ch + i;
  3821. c->dbV[ c->si ] = c->db;
  3822. c->hzV[ c->si ] = c->hz;
  3823. c->si = (c->si + 1) % p->sN;
  3824. c->sn += 1;
  3825. unsigned n = cmMin(c->sn,p->sN);
  3826. c->db_mean = cmVOR_Mean(c->dbV,n);
  3827. c->db_std = sqrt(cmVOR_Variance( c->dbV,n,&c->db_mean));
  3828. c->hz_mean = cmVOR_Mean(c->hzV,n);
  3829. c->hz_std = sqrt(cmVOR_Variance( c->hzV,n,&c->hz_mean));
  3830. //c->score = c->db / ((cmMax(0.1,c->db_std) + cmMax(0.1,c->hz_std))/2);
  3831. c->score = c->db - (c->db_std * 5) - (c->hz_std/50);
  3832. //printf("%f %f %f %f %f\n",c->db,cmMin(0.1,c->db_std),c->hz,cmMin(0.1,c->hz_std),c->score);
  3833. }
  3834. }
  3835. // Generate a filter that is wider for higher frequencies than lower frequencies.
  3836. unsigned _cmFrqTrkFillMap( cmFrqTrk* p, cmReal_t* map, unsigned maxN, cmReal_t hz )
  3837. {
  3838. assert( maxN % 2 == 1 );
  3839. unsigned i;
  3840. cmReal_t maxHz = p->a.srate/2;
  3841. unsigned mapN = cmMin(maxN,ceil(hz/maxHz * maxN));
  3842. if( mapN % 2 == 0 )
  3843. mapN += 1;
  3844. mapN = cmMin(maxN,mapN);
  3845. unsigned N = floor(mapN/2);
  3846. double COEFF = 0.3;
  3847. for(i=0; i<N; ++i)
  3848. {
  3849. map[i] = pow(((double)i+1)/(N+1),COEFF);
  3850. map[mapN-(i+1)] = map[i];
  3851. }
  3852. map[N] = 1.0;
  3853. return mapN;
  3854. }
  3855. void _cmFrqTrkApplyAtten( cmFrqTrk* p, cmReal_t* aV, cmReal_t gain, cmReal_t hz )
  3856. {
  3857. int cbi = cmMin(p->a.binCnt,cmMax(0,round(hz/p->binHz)));
  3858. //cmReal_t map[] = { .25, .5, 1, .5, .25 };
  3859. //int mapN = sizeof(map)/sizeof(map[0]);
  3860. unsigned maxN = 30; // must be odd
  3861. cmReal_t map[ maxN ];
  3862. int mapN = _cmFrqTrkFillMap(p, map, maxN, hz );
  3863. int j;
  3864. int ai = cbi - mapN/2;
  3865. for(j=0; j<mapN; ++j,++ai)
  3866. if( 0 <= ai && ai < p->a.binCnt )
  3867. aV[ai] *= 1.0 - (map[j] * gain);
  3868. }
  3869. void _cmFrqTrkUpdateFilter( cmFrqTrk* p )
  3870. {
  3871. unsigned i;
  3872. cmVOR_Fill(p->aV,p->a.binCnt,1.0);
  3873. for(i=0; i<p->a.chCnt; ++i)
  3874. if( p->ch[i].activeFl )
  3875. {
  3876. cmFrqTrkCh_t* c = p->ch + i;
  3877. //
  3878. if( c->score >= p->a.attenThresh && c->state == kNoStateFrqTrkId )
  3879. {
  3880. //printf("%f\n",c->score);
  3881. c->attenPhsIdx = 0;
  3882. c->state = kDlyFrqTrkId;
  3883. }
  3884. switch( c->state )
  3885. {
  3886. case kNoStateFrqTrkId:
  3887. break;
  3888. case kDlyFrqTrkId:
  3889. c->attenPhsIdx += 1;
  3890. if( c->attenPhsIdx >= p->attenDlyPhsMax && c->dN == 0 )
  3891. c->state = kAtkFrqTrkId;
  3892. break;
  3893. case kAtkFrqTrkId:
  3894. if( c->attenPhsIdx < p->attenDlyPhsMax + p->attenPhsMax )
  3895. {
  3896. c->attenGain = cmMin(1.0,p->a.attenGain * c->attenPhsIdx / p->attenPhsMax);
  3897. _cmFrqTrkApplyAtten(p, p->aV, c->attenGain, c->hz);
  3898. }
  3899. c->attenPhsIdx += 1;
  3900. if( c->attenPhsIdx >= p->attenDlyPhsMax + p->attenPhsMax )
  3901. c->state = kSusFrqTrkId;
  3902. break;
  3903. case kSusFrqTrkId:
  3904. if( c->dN > 0 )
  3905. {
  3906. if( c->attenPhsIdx > 0 )
  3907. {
  3908. c->attenPhsIdx -= 1;
  3909. c->attenGain = cmMin(1.0,p->a.attenGain * c->attenPhsIdx / p->attenPhsMax);
  3910. }
  3911. }
  3912. _cmFrqTrkApplyAtten(p,p->aV, c->attenGain, c->hz);
  3913. if( c->dN >= p->deadN_max )
  3914. c->state = kDcyFrqTrkId;
  3915. break;
  3916. case kDcyFrqTrkId:
  3917. if( c->attenPhsIdx > 0 )
  3918. {
  3919. c->attenPhsIdx -= 1;
  3920. c->attenGain = cmMin(1.0,p->a.attenGain * c->attenPhsIdx / p->attenPhsMax);
  3921. _cmFrqTrkApplyAtten(p,p->aV, c->attenGain, c->hz);
  3922. }
  3923. if( c->attenPhsIdx == 0 )
  3924. c->activeFl = false;
  3925. break;
  3926. }
  3927. }
  3928. }
  3929. // Extend the existing trackers
  3930. void _cmFrqTrkExtendChs( cmFrqTrk* p, const cmReal_t* dbV, const cmReal_t* hzV, unsigned* pkiV, unsigned pkN )
  3931. {
  3932. unsigned i;
  3933. p->curTrkCnt = 0;
  3934. p->deadTrkCnt = 0;
  3935. // sort the channels in descending order
  3936. qsort(p->ch,p->a.chCnt,sizeof(cmFrqTrkCh_t),_cmFrqTrkChCompare);
  3937. // for each active channel
  3938. for(i=0; i<p->a.chCnt; ++i)
  3939. {
  3940. cmFrqTrkCh_t* c = p->ch + i;
  3941. if( c->activeFl )
  3942. {
  3943. unsigned pki;
  3944. // find the best peak to extend tracker 'c'.
  3945. if((pki = _cmFrqTrkFindPeak(p,c,dbV,hzV,pkiV,pkN)) == cmInvalidIdx )
  3946. {
  3947. // no valid track was found to extend tracker 'c'
  3948. c->dN += 1;
  3949. c->tN += 1;
  3950. if( c->dN >= p->deadN_max )
  3951. {
  3952. if( c->attenPhsIdx == 0 )
  3953. c->activeFl = false;
  3954. p->deadTrkCnt += 1;
  3955. }
  3956. }
  3957. else // ... update the tracker using the matching peak
  3958. {
  3959. unsigned j = pkiV[pki];
  3960. c->dN = 0;
  3961. c->db = dbV[ j ];
  3962. c->hz = hzV[ j ];
  3963. c->tN += 1;
  3964. pkiV[pki] = cmInvalidIdx; // mark the peak as unavailable.
  3965. p->curTrkCnt += 1;
  3966. }
  3967. }
  3968. }
  3969. }
  3970. // disable peaks which are within 'stRange' semitones of the frequency of active trackers.
  3971. void _cmFrqTrkDisableClosePeaks( cmFrqTrk* p, const cmReal_t* dbV, const cmReal_t* hzV, unsigned* pkiV, unsigned pkN )
  3972. {
  3973. unsigned i;
  3974. for(i=0; i<p->a.chCnt; ++i)
  3975. {
  3976. const cmFrqTrkCh_t* c = p->ch + i;
  3977. if( !c->activeFl )
  3978. continue;
  3979. cmReal_t hz_min = c->hz * pow(2,-p->a.stRange/12.0);
  3980. cmReal_t hz_max = c->hz * pow(2, p->a.stRange/12.0);
  3981. unsigned j;
  3982. // find all peaks within the frequency range hz_min to hz_max.
  3983. for(j=0; j<pkN; ++j)
  3984. if( pkiV[j] != cmInvalidIdx && hz_min <= c->hz && c->hz <= hz_max )
  3985. pkiV[j] = cmInvalidIdx;
  3986. }
  3987. }
  3988. // Return the index into pkiV[] of the maximum energy peak in dbV[]
  3989. // that is also above kAtkThreshDb.
  3990. unsigned _cmFrqTrkMaxEnergyPeakIndex( const cmFrqTrk* p, const cmReal_t* dbV, const cmReal_t* hzV, const unsigned* pkiV, unsigned pkN )
  3991. {
  3992. cmReal_t mv = p->a.pkAtkThreshDb;
  3993. unsigned mi = cmInvalidIdx;
  3994. unsigned i;
  3995. for(i=0; i<pkN; ++i)
  3996. if( pkiV[i] != cmInvalidIdx && dbV[pkiV[i]] >= mv && hzV[pkiV[i]] < p->a.pkMaxHz )
  3997. {
  3998. mi = i;
  3999. mv = dbV[pkiV[i]];
  4000. }
  4001. return mi;
  4002. }
  4003. // start new trackers
  4004. void _cmFrqTrkNewChs( cmFrqTrk* p, const cmReal_t* dbV, const cmReal_t* hzV, unsigned* pkiV, unsigned pkN )
  4005. {
  4006. p->newTrkCnt = 0;
  4007. while(1)
  4008. {
  4009. unsigned db_max_idx;
  4010. cmFrqTrkCh_t* c;
  4011. // find an inactive channel
  4012. if((c = _cmFrqTrkFindAvailCh(p)) == NULL )
  4013. break;
  4014. // find the largest peak that is above pkAtkThreshDb && less than pkAtkHz.
  4015. if((db_max_idx = _cmFrqTrkMaxEnergyPeakIndex(p,dbV,hzV,pkiV,pkN)) == cmInvalidIdx )
  4016. break;
  4017. // activate a new channel
  4018. c->activeFl = true;
  4019. c->tN = 1;
  4020. c->dN = 0;
  4021. c->hz = hzV[ pkiV[ db_max_idx ] ];
  4022. c->db = dbV[ pkiV[ db_max_idx ] ];
  4023. c->id = p->nextTrkId++;
  4024. c->si = 0;
  4025. c->sn = 0;
  4026. c->score = 0;
  4027. c->state = kNoStateFrqTrkId;
  4028. c->attenPhsIdx = cmInvalidIdx;
  4029. c->attenGain = 1.0;
  4030. // mark the peak as unavailable
  4031. pkiV[ db_max_idx ] = cmInvalidIdx;
  4032. p->newTrkCnt += 1;
  4033. }
  4034. }
  4035. void _cmFrqTrkApplyFrqBias( cmFrqTrk* p, cmReal_t* xV )
  4036. {
  4037. // convert to decibel scale (0.0 - 100.0) and then scale to (0.0 to 1.0)
  4038. unsigned i;
  4039. for(i=0; i<p->bN; ++i)
  4040. xV[i] = cmMax(0.0, (20*log10( cmMax(xV[i]/1.5,0.00001)) + 100.0)/100.0);
  4041. }
  4042. cmRC_t cmFrqTrkExec( cmFrqTrk* p, const cmReal_t* magV, const cmReal_t* phsV, const cmReal_t* hertzV )
  4043. {
  4044. cmRC_t rc = cmOkRC;
  4045. cmReal_t hzV[ p->bN ];
  4046. //cmReal_t powV[ p->bN ];
  4047. //cmReal_t yV[ p->bN];
  4048. //cmVOR_MultVVV(powV,p->bN,magV,magV);
  4049. //cmWhFiltExec(p->wf,powV,p->dbV,p->bN);
  4050. // convert magV to Decibels
  4051. //cmVOR_AmplToDbVV(p->dbV,p->bN, magV, -200.0);
  4052. // copy p->dbV to dbM[hi,:]
  4053. //cmVOR_CopyN(p->dbM + p->hi, p->bN, p->hN, p->dbV, 1 );
  4054. //cmVOR_CopyN(p->dbM + p->hi, p->bN, p->hN, whV, 1 );
  4055. if( 1 )
  4056. {
  4057. cmReal_t powV[ p->bN ];
  4058. cmVOR_MultVVV(powV,p->bN,magV,magV);
  4059. cmWhFiltExec(p->wf,powV,p->dbV,p->bN);
  4060. _cmFrqTrkApplyFrqBias(p,p->dbV);
  4061. }
  4062. else
  4063. {
  4064. // convert magV to Decibels
  4065. cmVOR_AmplToDbVV(p->dbV,p->bN, magV, -200.0);
  4066. }
  4067. // copy p->dbV to dbM[hi,:]
  4068. cmVOR_CopyN(p->dbM + p->hi, p->bN, p->hN, p->dbV, 1 );
  4069. // increment hi to next column to fill in dbM[]
  4070. p->hi = (p->hi + 1) % p->hN;
  4071. // Set dbV[] to spectral magnitude profile by taking the mean over time
  4072. // of the last hN magnitude vectors
  4073. cmVOR_MeanM2(p->dbV, p->dbM, p->hN, p->bN, 0, cmMin(p->fN+1,p->hN));
  4074. //cmVOR_MeanM(p->dbV, p->dbM, p->hN, p->bN, 0);
  4075. if( p->fN >= p->hN )
  4076. {
  4077. // set pkiV[] to the indexes of the peaks above pkThreshDb in i0[]
  4078. unsigned pkN = cmVOR_PeakIndexes(p->pkiV, p->bN, p->dbV, p->bN, p->a.pkThreshDb );
  4079. // set hzV[] to the peak frequencies assoc'd with peaks at dbV[ pkiV[] ].
  4080. _cmFrqTrkMagnToHz(p, p->dbV, p->pkiV, pkN, hzV );
  4081. // extend the existing trackers
  4082. _cmFrqTrkExtendChs(p, p->dbV, hzV, p->pkiV, pkN );
  4083. //_cmFrqTrkDisableClosePeaks(p, p->dbV, hzV, p->pkiV, pkN );
  4084. // create new trackers
  4085. _cmFrqTrkNewChs(p,p->dbV,hzV,p->pkiV,pkN);
  4086. //
  4087. _cmFrqTrkScoreChs(p);
  4088. //
  4089. _cmFrqTrkUpdateFilter(p);
  4090. /*
  4091. // write the log file
  4092. _cmFrqTrkWriteLog(p);
  4093. // write the spectrum output file
  4094. if( p->specFn != NULL )
  4095. cmVectArrayAppendR(p->specVa,p->dbV,p->bN);
  4096. // write the atten output file
  4097. if( p->attenFn != NULL )
  4098. cmVectArrayAppendR(p->attenVa,p->aV,p->bN);
  4099. // write the the level file
  4100. _cmFrqTrkWriteLevel(p,p->dbV,hzV,p->bN);
  4101. */
  4102. }
  4103. p->fN += 1;
  4104. return rc;
  4105. }
  4106. void cmFrqTrkPrint( cmFrqTrk* p )
  4107. {
  4108. printf("srate: %f\n",p->a.srate);
  4109. printf("chCnt: %i\n",p->a.chCnt);
  4110. printf("binCnt: %i (bN=%i)\n",p->a.binCnt,p->bN);
  4111. printf("hopSmpCnt: %i\n",p->a.hopSmpCnt);
  4112. printf("stRange: %f\n",p->a.stRange);
  4113. printf("wndSecs: %f (%i)\n",p->a.wndSecs,p->hN);
  4114. printf("minTrkSec: %f (%i)\n",p->a.minTrkSec,p->minTrkN);
  4115. printf("maxTrkDeadSec: %f (%i)\n",p->a.maxTrkDeadSec,p->deadN_max);
  4116. printf("pkThreshDb: %f\n",p->a.pkThreshDb);
  4117. printf("pkAtkThreshDb: %f\n",p->a.pkAtkThreshDb);
  4118. }
  4119. //------------------------------------------------------------------------------------------------------------
  4120. cmFbCtl_t* cmFbCtlAlloc( cmCtx* c, cmFbCtl_t* ap, const cmFbCtlArgs_t* a )
  4121. {
  4122. cmFbCtl_t* p = cmObjAlloc( cmFbCtl_t, c, ap );
  4123. p->sva = cmVectArrayAlloc(c,kRealVaFl);
  4124. p->uva = cmVectArrayAlloc(c,kRealVaFl);
  4125. if( a != NULL )
  4126. {
  4127. if( cmFbCtlInit( p, a ) != cmOkRC )
  4128. cmFbCtlFree(&p);
  4129. }
  4130. return p;
  4131. }
  4132. cmRC_t cmFbCtlFree( cmFbCtl_t** pp )
  4133. {
  4134. if( pp == NULL || *pp == NULL )
  4135. return cmOkRC;
  4136. cmFbCtl_t* p = *pp;
  4137. cmVectArrayWrite(p->sva, "/home/kevin/temp/frqtrk/fb_ctl_s.va");
  4138. cmVectArrayWrite(p->uva, "/home/kevin/temp/frqtrk/fb_ctl_u.va");
  4139. cmMemFree(p->bM);
  4140. cmMemFree(p->rmsV);
  4141. cmVectArrayFree(&p->sva);
  4142. cmVectArrayFree(&p->uva);
  4143. cmObjFree(pp);
  4144. return cmOkRC;
  4145. }
  4146. cmRC_t cmFbCtlInit( cmFbCtl_t* p, const cmFbCtlArgs_t* a )
  4147. {
  4148. cmRC_t rc;
  4149. if((rc = cmFbCtlFinal(p)) != cmOkRC )
  4150. return rc;
  4151. double binHz = a->srate / ((a->binCnt-1)*2);
  4152. p->a = *a;
  4153. p->frmCnt = (a->bufMs * a->srate / 1000.0) /a->hopSmpCnt;
  4154. p->binCnt = cmMin(p->a.binCnt, a->maxHz/binHz);
  4155. p->bM = cmMemResizeZ(cmReal_t, p->bM, p->binCnt*p->frmCnt);
  4156. p->rmsV = cmMemResizeZ(cmReal_t, p->rmsV, p->frmCnt);
  4157. p->sV = cmMemResizeZ(cmReal_t, p->sV, p->binCnt);
  4158. p->uV = cmMemResizeZ(cmReal_t, p->uV, p->binCnt);
  4159. printf("cmFbCtl: frmCnt:%i binCnt:%i \n",p->frmCnt,p->binCnt);
  4160. return rc;
  4161. }
  4162. cmRC_t cmFbCtlFinal(cmFbCtl_t* p )
  4163. { return cmOkRC; }
  4164. cmRC_t cmFbCtlExec( cmFbCtl_t* p, const cmReal_t* x0V )
  4165. {
  4166. unsigned i;
  4167. cmRC_t rc = cmOkRC;
  4168. cmReal_t xV[ p->binCnt ];
  4169. cmVOR_AmplToDbVV(xV, p->binCnt, x0V, -1000.0 );
  4170. cmVOR_Shift( p->rmsV, p->frmCnt, -1, 0 );
  4171. p->rmsV[0] = cmVOR_Mean(xV,p->binCnt);
  4172. cmVOR_CopyN(p->bM + p->bfi, p->binCnt, p->frmCnt, xV, 1 );
  4173. p->bfi = (p->bfi + 1) % p->frmCnt;
  4174. p->bfN = cmMin(p->bfN+1,p->frmCnt);
  4175. for(i=0; i<p->binCnt; ++i)
  4176. {
  4177. const cmReal_t* v = p->bM + i * p->frmCnt;
  4178. cmReal_t u = cmVOR_Mean(v, p->bfN );
  4179. cmReal_t s = sqrt(cmVOR_Variance(v, p->bfN,&u));
  4180. p->sV[i] = (0.0002 - s);
  4181. p->uV[i] = u;
  4182. }
  4183. cmVectArrayAppendR(p->sva,p->sV,p->binCnt);
  4184. cmVectArrayAppendR(p->uva,p->uV,p->binCnt);
  4185. return rc;
  4186. }
  4187. //=======================================================================================================================
  4188. cmExpander* cmExpanderAlloc( cmCtx* c, cmExpander* p,
  4189. double srate, unsigned procSmpCnt, double threshDb, double rlsDb,
  4190. double threshMs, double rmsMs, double atkMs, double rlsMs )
  4191. {
  4192. cmExpander* op = cmObjAlloc(cmExpander,c,p);
  4193. if( srate > 0 )
  4194. if( cmExpanderInit(op,srate, procSmpCnt, threshDb, rlsDb, threshMs, rmsMs, atkMs, rlsMs) != cmOkRC )
  4195. cmExpanderFree(&op);
  4196. return op;
  4197. }
  4198. cmRC_t cmExpanderFree( cmExpander** pp )
  4199. {
  4200. cmRC_t rc = cmOkRC;
  4201. if( pp==NULL || *pp==NULL )
  4202. return rc;
  4203. cmExpander* p = *pp;
  4204. if((rc = cmExpanderFinal(p)) != cmOkRC )
  4205. return rc;
  4206. cmMemFree(p->rmsV);
  4207. cmMemFree(p->envV);
  4208. cmObjFree(pp);
  4209. return rc;
  4210. }
  4211. cmRC_t cmExpanderInit( cmExpander* p,
  4212. double srate, unsigned procSmpCnt, double threshDb, double rlsDb,
  4213. double threshMs, double rmsMs, double atkMs, double rlsMs )
  4214. {
  4215. cmRC_t rc;
  4216. unsigned i;
  4217. if((rc = cmExpanderFinal(p)) != cmOkRC )
  4218. return rc;
  4219. unsigned atkN = cmMax(1,ceil( atkMs / (srate * 1000.0)));
  4220. unsigned rlsN = cmMax(1,ceil( rlsMs / (srate * 1000.0)));
  4221. p->rmsN = cmMax(1,ceil(rmsMs / (srate * 1000.0)));
  4222. p->rmsV = cmMemResizeZ(cmReal_t,p->rmsV,p->rmsN);
  4223. p->rmsIdx = 0;
  4224. p->envN = atkN + rlsN;
  4225. p->envV = cmMemResizeZ(cmSample_t,p->envV,p->envN);
  4226. p->envIdx = p->envN;
  4227. p->threshN = cmMax(1,ceil(threshMs / (srate * 1000.0)));
  4228. p->threshIdx = 0;
  4229. p->threshLvl = pow(10.0,(threshDb/20.0));
  4230. p->rlsLvl = pow(10.0,(rlsDb/20.0));
  4231. p->gain = 1.0;
  4232. p->atkCnt = 0;
  4233. cmSample_t G = (1.0 - p->rlsLvl);
  4234. for(i=0; i<atkN; ++i)
  4235. {
  4236. p->envV[i] = 1.0 - G*i/atkN;
  4237. }
  4238. for(i=0; i<rlsN; ++i)
  4239. {
  4240. p->envV[atkN+i] = p->rlsLvl + (G*i/rlsN);
  4241. }
  4242. printf("rmsN:%i atkN:%i rlsN:%i thr:%f %f rls:%f %f\n",p->rmsN,atkN,rlsN,threshDb,p->threshLvl,rlsDb,p->rlsLvl);
  4243. //for(i=0; i<p->envN; ++i)
  4244. // printf("%i %f\n",i,p->envV[i]);
  4245. //printf("\n");
  4246. return cmOkRC;
  4247. }
  4248. cmRC_t cmExpanderFinal( cmExpander* p )
  4249. { return cmOkRC; }
  4250. cmRC_t cmExpanderExec( cmExpander* p, cmSample_t* x, cmSample_t* y, unsigned xyN )
  4251. {
  4252. unsigned i;
  4253. // update the RMS buffer
  4254. for(i=0; i<xyN; ++i)
  4255. {
  4256. // NOTE: using abs() instead of pow(x,2)
  4257. p->rmsV[p->rmsIdx] = abs(x[i]);
  4258. if( ++p->rmsIdx >= p->rmsN )
  4259. p->rmsIdx = 0;
  4260. }
  4261. // calculate the RMS
  4262. double rms = cmVOR_Mean(p->rmsV,p->rmsN);
  4263. // update the duration that the signal has been above the threshold
  4264. if( rms > p->threshLvl )
  4265. p->threshIdx += 1;
  4266. else
  4267. p->threshIdx = 0;
  4268. // begin the atk phase?
  4269. if( p->threshIdx > p->threshN && p->envIdx >= p->envN )
  4270. {
  4271. p->envIdx = 0;
  4272. }
  4273. // update the output
  4274. if( p->envIdx >= p->envN )
  4275. {
  4276. if( y != NULL )
  4277. cmVOS_Copy(y,xyN,x);
  4278. }
  4279. else
  4280. {
  4281. if( y == NULL )
  4282. y = x;
  4283. for(i=0; i<xyN && p->envIdx<p->envN; ++i,++p->envIdx)
  4284. y[i] = p->envV[p->envIdx] * x[i];
  4285. }
  4286. return cmOkRC;
  4287. }
  4288. cmRC_t cmExpanderExecD( cmExpander* p, double* x, double* y, unsigned xyN )
  4289. {
  4290. unsigned i;
  4291. // update the RMS buffer
  4292. for(i=0; i<xyN; ++i)
  4293. {
  4294. // NOTE: using abs() instead of pow(x,2)
  4295. p->rmsV[p->rmsIdx] = x[i];
  4296. p->rmsIdx += 1;
  4297. if( p->rmsIdx >= p->rmsN )
  4298. p->rmsIdx = 0;
  4299. }
  4300. // calculate the RMS
  4301. p->rmsValue = cmVOR_Mean(p->rmsV,p->rmsN);
  4302. // update the duration that the signal has been above the threshold
  4303. if( p->rmsValue > p->threshLvl )
  4304. p->threshIdx += 1;
  4305. else
  4306. p->threshIdx = 0;
  4307. // begin the atk phase?
  4308. if( p->threshIdx > p->threshN && p->envIdx >= p->envN )
  4309. {
  4310. p->envIdx = 0;
  4311. p->atkCnt += 1;
  4312. }
  4313. /*
  4314. if( p->envIdx >= p->envN )
  4315. p->gain = 1.0;
  4316. else
  4317. {
  4318. p->gain = p->envV[p->envIdx];
  4319. p->envIdx += 1;
  4320. }
  4321. */
  4322. // update the output
  4323. if( p->envIdx >= p->envN )
  4324. {
  4325. if( y != NULL )
  4326. cmVOD_Copy(y,xyN,x);
  4327. }
  4328. else
  4329. {
  4330. if( y == NULL )
  4331. y = x;
  4332. for(i=0; i<xyN && p->envIdx<p->envN; ++i,++p->envIdx)
  4333. y[i] = p->envV[p->envIdx] * x[i];
  4334. }
  4335. return cmOkRC;
  4336. }
  4337. //=======================================================================================================================
  4338. cmExpanderBank* cmExpanderBankAlloc( cmCtx* c, cmExpanderBank* p, unsigned bandN, double srate, unsigned procSmpCnt, double threshDb, double rlsDb, double threshMs, double rmsMs, double atkMs, double rlsMs )
  4339. {
  4340. cmExpanderBank* op = cmObjAlloc(cmExpanderBank,c,p);
  4341. if( bandN > 0 )
  4342. if( cmExpanderBankInit(op,bandN,srate, procSmpCnt, threshDb, rlsDb, threshMs, rmsMs, atkMs, rlsMs) != cmOkRC )
  4343. cmExpanderBankFree(&op);
  4344. return op;
  4345. }
  4346. cmRC_t cmExpanderBankFree( cmExpanderBank** pp )
  4347. {
  4348. cmRC_t rc = cmOkRC;
  4349. if( pp==NULL || *pp==NULL )
  4350. return rc;
  4351. cmExpanderBank* p = *pp;
  4352. if((rc = cmExpanderBankFinal(p)) != cmOkRC )
  4353. return rc;
  4354. cmMemFree(p->b);
  4355. cmObjFree(pp);
  4356. return rc;
  4357. }
  4358. cmRC_t cmExpanderBankInit( cmExpanderBank* p, unsigned bandN, double srate, unsigned procSmpCnt, double threshDb, double rlsDb, double threshMs, double rmsMs, double atkMs, double rlsMs )
  4359. {
  4360. cmRC_t rc;
  4361. unsigned i;
  4362. if((rc = cmExpanderBankFinal(p)) != cmOkRC )
  4363. return rc;
  4364. p->bandN = bandN;
  4365. p->b = cmMemResizeZ(cmExpander*,p->b,p->bandN);
  4366. for(i=0; i<bandN; ++i)
  4367. p->b[i] = cmExpanderAlloc(p->obj.ctx,NULL,srate, procSmpCnt,threshDb,rlsDb,threshMs,rmsMs,atkMs,rlsMs);
  4368. return cmOkRC;
  4369. }
  4370. cmRC_t cmExpanderBankFinal( cmExpanderBank* p )
  4371. {
  4372. unsigned i;
  4373. for(i=0; i<p->bandN; ++i)
  4374. cmExpanderFree(&p->b[i]);
  4375. return cmOkRC;
  4376. }
  4377. cmRC_t cmExpanderBankExec( cmExpanderBank* p, cmSample_t* x, unsigned bandN )
  4378. {
  4379. assert( bandN <= p->bandN);
  4380. unsigned i;
  4381. for(i=0; i<bandN; ++i)
  4382. {
  4383. cmExpanderExec(p->b[i],&x[i],NULL,1);
  4384. }
  4385. return cmOkRC;
  4386. }
  4387. /*
  4388. cmRC_t cmExpanderBankExecD( cmExpanderBank* p, double* x, unsigned binN )
  4389. {
  4390. unsigned i;
  4391. p->rmsValue = 0;
  4392. for(i=0; i<p->bandN; ++i)
  4393. {
  4394. double sum = cmVOD_Sum(x,binN);
  4395. cmExpanderExecD(p->b[i],&sum,NULL,1);
  4396. //printf("%f %f\n",sum, p->b[i]->rmsValue);
  4397. p->rmsValue += p->b[i]->rmsValue;
  4398. cmVOR_MultVS(x,binN,p->b[i]->gain);
  4399. }
  4400. p->rmsValue /= p->bandN;
  4401. return cmOkRC;
  4402. }
  4403. */
  4404. cmRC_t cmExpanderBankExecD( cmExpanderBank* p, double* x, unsigned bandN )
  4405. {
  4406. unsigned i;
  4407. //unsigned n = 3;
  4408. //unsigned no2 = n/2;
  4409. double xx;
  4410. p->rmsValue = 0;
  4411. p->atkCnt = 0;
  4412. for(i=0; i<p->bandN; ++i)
  4413. {
  4414. unsigned atkCnt = p->b[i]->atkCnt;
  4415. //if( i >= no2 && i < bandN-no2 )
  4416. // xx = cmVOR_Mean(x-no2,n);
  4417. //else
  4418. xx = x[i];
  4419. cmExpanderExecD(p->b[i],&xx,NULL,1);
  4420. p->rmsValue += p->b[i]->rmsValue;
  4421. p->atkCnt += p->b[i]->atkCnt != atkCnt;
  4422. }
  4423. p->rmsValue /= p->bandN;
  4424. return cmOkRC;
  4425. }
  4426. //------------------------------------------------------------------------------------------------------------
  4427. cmSpecDist_t* cmSpecDistAlloc( cmCtx* ctx,cmSpecDist_t* ap, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopFcmt, unsigned olaWndTypeId )
  4428. {
  4429. cmSpecDist_t* p = cmObjAlloc( cmSpecDist_t, ctx, ap );
  4430. //p->iSpecVa = cmVectArrayAlloc(ctx,kRealVaFl);
  4431. p->oSpecVa = cmVectArrayAlloc(ctx,kRealVaFl);
  4432. if( procSmpCnt != 0 )
  4433. {
  4434. if( cmSpecDistInit( p, procSmpCnt, srate, wndSmpCnt, hopFcmt, olaWndTypeId ) != cmOkRC )
  4435. cmSpecDistFree(&p);
  4436. }
  4437. return p;
  4438. }
  4439. cmRC_t cmSpecDistFree( cmSpecDist_t** pp )
  4440. {
  4441. if( pp == NULL || *pp == NULL )
  4442. return cmOkRC;
  4443. cmSpecDist_t* p = *pp;
  4444. cmSpecDistFinal(p);
  4445. //cmVectArrayFree(&p->iSpecVa);
  4446. cmVectArrayFree(&p->oSpecVa);
  4447. cmMemPtrFree(&p->hzV);
  4448. cmMemPtrFree(&p->iSpecM);
  4449. cmMemPtrFree(&p->oSpecM);
  4450. cmMemPtrFree(&p->iSpecV);
  4451. cmMemPtrFree(&p->oSpecV);
  4452. cmObjFree(pp);
  4453. return cmOkRC;
  4454. }
  4455. cmRC_t cmSpecDistInit( cmSpecDist_t* p, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopFcmt, unsigned olaWndTypeId )
  4456. {
  4457. //cmFrqTrkArgs_t fta;
  4458. cmRC_t rc;
  4459. if((rc = cmSpecDistFinal(p)) != cmOkRC )
  4460. return rc;
  4461. unsigned flags = 0;
  4462. p->srate = srate;
  4463. p->wndSmpCnt = wndSmpCnt;
  4464. p->hopSmpCnt = (unsigned)floor(wndSmpCnt/hopFcmt);
  4465. p->procSmpCnt = procSmpCnt;
  4466. p->mode = kBasicModeSdId;
  4467. p->thresh = 60;
  4468. p->offset = 0;
  4469. p->invertFl = false;
  4470. p->uprSlope = 0.0;
  4471. p->lwrSlope = 2.0;
  4472. p->pva = cmPvAnlAlloc( p->obj.ctx, NULL, procSmpCnt, srate, wndSmpCnt, p->hopSmpCnt, flags );
  4473. p->pvs = cmPvSynAlloc( p->obj.ctx, NULL, procSmpCnt, srate, wndSmpCnt, p->hopSmpCnt, olaWndTypeId );
  4474. /*
  4475. fta.srate = srate;
  4476. fta.chCnt = 50;
  4477. fta.binCnt = p->pva->binCnt;
  4478. fta.hopSmpCnt = p->pva->hopSmpCnt;
  4479. fta.stRange = 0.25;
  4480. fta.wndSecs = 0.25;
  4481. fta.minTrkSec = 0.25;
  4482. fta.maxTrkDeadSec = 0.25;
  4483. fta.pkThreshDb = 0.1; //-110.0;
  4484. fta.pkAtkThreshDb = 0.4; //-60.0;
  4485. fta.pkMaxHz = 20000;
  4486. fta.whFiltCoeff = 0.33;
  4487. fta.attenThresh = 0.4;
  4488. fta.attenGain = 0.5;
  4489. fta.attenDlySec = 1.0;
  4490. fta.attenAtkSec = 1.0;
  4491. fta.logFn = "/home/kevin/temp/frqtrk/trk_log.va";
  4492. fta.levelFn = "/home/kevin/temp/frqtrk/level.va";
  4493. fta.specFn = "/home/kevin/temp/frqtrk/spec.va";
  4494. fta.attenFn = "/home/kevin/temp/frqtrk/atten.va";
  4495. */
  4496. //p->ft = cmFrqTrkAlloc( p->obj.ctx, NULL, &fta );
  4497. /*
  4498. cmFbCtlArgs_t fba;
  4499. fba.srate = srate;
  4500. fba.binCnt = p->pva->binCnt;
  4501. fba.hopSmpCnt = p->hopSmpCnt;
  4502. fba.bufMs = 500;
  4503. fba.maxHz = 5000;
  4504. */
  4505. //p->fbc = cmFbCtlAlloc( p->obj.ctx, NULL, &fba );
  4506. //unsigned expBandN = 1; //
  4507. unsigned expBandN = 20000.0 / (p->srate / p->pva->binCnt);
  4508. double expSrate = p->pva->hopSmpCnt / srate;
  4509. unsigned expProcSmpCnt = 1;
  4510. double expThreshDb = -80.0;
  4511. double expRlsDb = -18.0;
  4512. double expThreshMs = 250.0;
  4513. double expRmsMs = 100.0;
  4514. double expAtkMs = 25.0;
  4515. double expRlsMs = 1000.0;
  4516. p->exb = cmExpanderBankAlloc( p->obj.ctx, NULL, expBandN, expSrate, expProcSmpCnt, expThreshDb, expRlsDb, expThreshMs, expRmsMs, expAtkMs, expRlsMs );
  4517. p->spcBwHz = cmMin(srate/2,10000);
  4518. p->spcSmArg = 0.05;
  4519. p->spcMin = p->spcBwHz;
  4520. p->spcMax = 0.0;
  4521. p->spcSum = 0.0;
  4522. p->spcCnt = 0;
  4523. double binHz = srate / p->pva->wndSmpCnt;
  4524. p->spcBinCnt = (unsigned)floor(p->spcBwHz / binHz);
  4525. p->hzV = cmMemResizeZ(cmReal_t,p->hzV,p->spcBinCnt);
  4526. cmVOR_Seq( p->hzV, p->spcBinCnt, 0, 1 );
  4527. cmVOR_MultVS( p->hzV, p->spcBinCnt, binHz );
  4528. p->aeUnit = 0;
  4529. p->aeMin = 1000;
  4530. p->aeMax = -1000;
  4531. double histSecs = 0.05;
  4532. p->hN = cmMax(1,histSecs * p->srate / p->hopSmpCnt );
  4533. p->iSpecM = cmMemResizeZ(cmReal_t,p->iSpecM,p->hN*p->pva->binCnt);
  4534. p->oSpecM = cmMemResizeZ(cmReal_t,p->oSpecM,p->hN*p->pva->binCnt);
  4535. p->iSpecV = cmMemResizeZ(cmReal_t,p->iSpecV, p->pva->binCnt);
  4536. p->oSpecV = cmMemResizeZ(cmReal_t,p->oSpecV, p->pva->binCnt);
  4537. p->hi = 0;
  4538. //p->bypOut = cmMemResizeZ(cmSample_t, p->bypOut, procSmpCnt );
  4539. return rc;
  4540. }
  4541. cmRC_t cmSpecDistFinal(cmSpecDist_t* p )
  4542. {
  4543. cmRC_t rc = cmOkRC;
  4544. //cmVectArrayWrite(p->iSpecVa, "/home/kevin/temp/frqtrk/iSpec.va");
  4545. cmVectArrayWrite(p->oSpecVa, "/home/kevin/temp/expand/oSpec.va");
  4546. cmPvAnlFree(&p->pva);
  4547. cmPvSynFree(&p->pvs);
  4548. //cmFrqTrkFree(&p->ft);
  4549. //cmFbCtlFree(&p->fbc);
  4550. cmExpanderBankFree(&p->exb);
  4551. return rc;
  4552. }
  4553. void _cmSpecDistBasicMode0(cmSpecDist_t* p, cmReal_t* X1m, unsigned binCnt, cmReal_t thresh )
  4554. {
  4555. // octavez> thresh = 60;
  4556. // octave> X1m = [-62 -61 -60 -59];
  4557. // octave> -abs(abs(X1m+thresh)-(X1m+thresh)) - thresh
  4558. // octave> ans = -64 -62 -60 -60
  4559. unsigned i=0;
  4560. for(i=0; i<binCnt; ++i)
  4561. {
  4562. cmReal_t a = fabs(X1m[i]);
  4563. cmReal_t d = a - thresh;
  4564. X1m[i] = -thresh;
  4565. if( d > 0 )
  4566. X1m[i] -= 2*d;
  4567. }
  4568. }
  4569. void _cmSpecDistBasicMode(cmSpecDist_t* p, cmReal_t* X1m, unsigned binCnt, cmReal_t thresh )
  4570. {
  4571. unsigned i=0;
  4572. if( p->lwrSlope < 0.3 )
  4573. p->lwrSlope = 0.3;
  4574. for(i=0; i<binCnt; ++i)
  4575. {
  4576. cmReal_t a = fabs(X1m[i]);
  4577. cmReal_t d = a - thresh;
  4578. X1m[i] = -thresh;
  4579. if( d > 0 )
  4580. X1m[i] -= (p->lwrSlope*d);
  4581. else
  4582. X1m[i] -= (p->uprSlope*d);
  4583. }
  4584. }
  4585. cmReal_t _cmSpecDistCentMode( cmSpecDist_t* p, cmReal_t* X1m )
  4586. {
  4587. // calc the spectral centroid
  4588. double num = cmVOR_MultSumVV( p->pva->magV, p->hzV, p->spcBinCnt );
  4589. double den = cmVOR_Sum( p->pva->magV, p->spcBinCnt );
  4590. double result = 0;
  4591. if( den != 0 )
  4592. result = num/den;
  4593. // apply smoothing filter to spectral centroid
  4594. p->spc = (result * p->spcSmArg) + (p->spc * (1.0-p->spcSmArg));
  4595. // track spec. cetr. min and max
  4596. p->spcMin = cmMin(p->spcMin,p->spc);
  4597. p->spcMax = cmMax(p->spcMax,p->spc);
  4598. //-----------------------------------------------------
  4599. ++p->spcCnt;
  4600. p->spcSum += p->spc;
  4601. p->spcSqSum += p->spc * p->spc;
  4602. // use the one-pass std-dev calc. trick
  4603. //double mean = p->spcSum / p->spcCnt;
  4604. //double variance = p->spcSqSum / p->spcCnt - mean * mean;
  4605. //double std_dev = sqrt(variance);
  4606. double smin = p->spcMin;
  4607. double smax = p->spcMax;
  4608. //smin = mean - std_dev;
  4609. //smax = mean + std_dev;
  4610. //-----------------------------------------------------
  4611. // convert spec. cent. to unit range
  4612. double spcUnit = (p->spc - smin) / (smax - smin);
  4613. spcUnit = cmMin(1.0,cmMax(0.0,spcUnit));
  4614. if( p->invertFl )
  4615. spcUnit = 1.0 - spcUnit;
  4616. //if( p->spcMin==p->spc || p->spcMax==p->spc )
  4617. // printf("min:%f avg:%f sd:%f max:%f\n",p->spcMin,p->spcSum/p->spcCnt,std_dev,p->spcMax);
  4618. return spcUnit;
  4619. }
  4620. void _cmSpecDistBump( cmSpecDist_t* p, cmReal_t* x, unsigned binCnt, double thresh)
  4621. {
  4622. /*
  4623. thresh *= -1;
  4624. minDb = -100;
  4625. if db < minDb
  4626. db = minDb;
  4627. endif
  4628. if db > thresh
  4629. y = 1;
  4630. else
  4631. x = (minDb - db)/(minDb - thresh);
  4632. y = x + (x - (x.^coeff));
  4633. endif
  4634. y = minDb + abs(minDb) * y;
  4635. */
  4636. unsigned i=0;
  4637. //printf("%f %f %f\n",thresh,p->lwrSlope,x[0]);
  4638. double minDb = -100.0;
  4639. thresh = -thresh;
  4640. for(i=0; i<binCnt; ++i)
  4641. {
  4642. double y;
  4643. if( x[i] < minDb )
  4644. x[i] = minDb;
  4645. if( x[i] > thresh )
  4646. y = 1;
  4647. else
  4648. {
  4649. y = (minDb - x[i])/(minDb - thresh);
  4650. y += y - pow(y,p->lwrSlope);
  4651. }
  4652. x[i] = minDb + (-minDb) * y;
  4653. }
  4654. }
  4655. void _cmSpecDistAmpEnvMode( cmSpecDist_t* p, cmReal_t* X1m )
  4656. {
  4657. cmReal_t smCoeff = 0.1;
  4658. //
  4659. cmReal_t mx = cmVOR_Max(X1m,p->pva->binCnt,1);
  4660. p->aeSmMax = (mx * smCoeff) + (p->aeSmMax * (1.0-smCoeff));
  4661. cmReal_t a = cmVOR_Mean(X1m,p->pva->binCnt);
  4662. p->ae = (a * smCoeff) + (p->ae * (1.0-smCoeff));
  4663. p->aeMin = cmMin(p->ae,p->aeMin);
  4664. p->aeMax = cmMax(p->ae,p->aeMax);
  4665. p->aeUnit = (p->ae - p->aeMin) / (p->aeMax-p->aeMin);
  4666. p->aeUnit = cmMin(1.0,cmMax(0.0,p->aeUnit));
  4667. if( p->invertFl )
  4668. p->aeUnit = 1.0 - p->aeUnit;
  4669. //printf("%f\n",p->aeSmMax);
  4670. }
  4671. void _cmSpecDistPhaseMod( cmSpecDist_t* p, cmReal_t* phsV, unsigned binCnt )
  4672. {
  4673. unsigned i;
  4674. cmReal_t offs = sin( 0.1 * 2.0 * M_PI * (p->phaseModIndex++) / (p->srate/p->hopSmpCnt) );
  4675. //printf("offs %f %i %i %f\n",offs,p->phaseModIndex,p->hopSmpCnt,p->srate);
  4676. cmReal_t new_phs = phsV[0] + offs;
  4677. for(i=0; i<binCnt-1; ++i)
  4678. {
  4679. while( new_phs > M_PI )
  4680. new_phs -= 2.0*M_PI;
  4681. while( new_phs < -M_PI )
  4682. new_phs += 2.0*M_PI;
  4683. cmReal_t d = phsV[i+1] - phsV[i];
  4684. phsV[i] = new_phs;
  4685. new_phs += d;
  4686. }
  4687. }
  4688. cmRC_t cmSpecDistExec( cmSpecDist_t* p, const cmSample_t* sp, unsigned sn )
  4689. {
  4690. assert( sn == p->procSmpCnt );
  4691. bool recordFl = false;
  4692. // cmPvAnlExec() returns true when it calc's a new spectral output frame
  4693. if( cmPvAnlExec( p->pva, sp, sn ) )
  4694. {
  4695. cmReal_t X1m[p->pva->binCnt];
  4696. // take the mean of the the input magntitude spectrum
  4697. cmReal_t u0 = cmVOR_Mean(p->pva->magV,p->pva->binCnt);
  4698. if(recordFl)
  4699. {
  4700. // store a time windowed average of the input spectrum to p->iSpecV
  4701. cmVOR_CopyN(p->iSpecM + p->hi, p->pva->binCnt, p->hN, X1m, 1 );
  4702. cmVOR_MeanM2(p->iSpecV, p->iSpecM, p->hN, p->pva->binCnt, 0, cmMin(p->fi+1,p->hN));
  4703. }
  4704. cmVOR_AmplToDbVV(X1m, p->pva->binCnt, p->pva->magV, -1000.0 );
  4705. //cmVOR_AmplToDbVV(X1m, p->pva->binCnt, X1m, -1000.0 );
  4706. switch( p->mode )
  4707. {
  4708. case kBypassModeSdId:
  4709. break;
  4710. case kBasicModeSdId:
  4711. _cmSpecDistBasicMode(p,X1m,p->pva->binCnt,p->thresh);
  4712. break;
  4713. case kSpecCentSdId:
  4714. {
  4715. _cmSpecDistAmpEnvMode(p,X1m);
  4716. double spcUnit = _cmSpecDistCentMode(p,X1m);
  4717. double thresh = fabs(p->aeSmMax) - (spcUnit*p->offset);
  4718. _cmSpecDistBasicMode(p,X1m,p->pva->binCnt, thresh);
  4719. }
  4720. break;
  4721. case kAmpEnvSdId:
  4722. {
  4723. _cmSpecDistAmpEnvMode(p,X1m);
  4724. //double thresh = fabs(p->aeSmMax) - p->offset;
  4725. double thresh = fabs(p->aeSmMax) - (p->aeUnit*p->offset);
  4726. thresh = fabs(p->thresh) - (p->aeUnit*p->offset);
  4727. _cmSpecDistBasicMode(p,X1m,p->pva->binCnt, thresh);
  4728. }
  4729. break;
  4730. case kBumpSdId:
  4731. _cmSpecDistBump(p,X1m, p->pva->binCnt, p->offset);
  4732. _cmSpecDistBasicMode(p,X1m,p->pva->binCnt,p->thresh);
  4733. break;
  4734. case 5:
  4735. break;
  4736. default:
  4737. break;
  4738. }
  4739. cmVOR_DbToAmplVV(X1m, p->pva->binCnt, X1m );
  4740. // run and apply the tracker/supressor
  4741. //cmFrqTrkExec(p->ft, X1m, p->pva->phsV, NULL );
  4742. //cmVOR_MultVV(X1m, p->pva->binCnt,p->ft->aV );
  4743. // convert the mean input magnitude to db
  4744. cmReal_t idb = 20*log10(u0);
  4745. // get the mean output magnitude spectra
  4746. cmReal_t u1 = cmVOR_Mean(X1m,p->pva->binCnt);
  4747. if( idb > -150.0 )
  4748. {
  4749. // set the output gain such that the mean output magnitude
  4750. // will match the mean input magnitude
  4751. p->ogain = u0/u1;
  4752. }
  4753. else
  4754. {
  4755. cmReal_t a0 = 0.9;
  4756. p->ogain *= a0;
  4757. }
  4758. cmVOR_MultVS(X1m,p->pva->binCnt,cmMin(4.0,p->ogain));
  4759. //cmFbCtlExec(p->fbc,X1m);
  4760. //cmReal_t v[ p->pva->binCnt ];
  4761. //cmVOR_Copy(v,p->pva->binCnt,p->pva->phsV);
  4762. //_cmSpecDistPhaseMod(p, v, p->pva->binCnt );
  4763. if(recordFl)
  4764. {
  4765. // store a time windowed average of the output spectrum to p->iSpecV
  4766. cmVOR_CopyN(p->oSpecM + p->hi, p->pva->binCnt, p->hN, X1m, 1 );
  4767. cmVOR_MeanM2(p->oSpecV, p->oSpecM, p->hN, p->pva->binCnt, 0, cmMin(p->fi+1,p->hN));
  4768. // store iSpecV and oSpecV to iSpecVa and oSpecVa to create debugging files
  4769. //cmVectArrayAppendR(p->iSpecVa,p->iSpecV,p->pva->binCnt);
  4770. //cmVectArrayAppendR(p->oSpecVa,p->oSpecV,p->pva->binCnt);
  4771. p->hi = (p->hi + 1) % p->hN;
  4772. }
  4773. //unsigned binN = 12500.0 / (p->srate / p->pva->binCnt);
  4774. //cmExpanderBankExecD(p->exb, X1m, binN );
  4775. /*
  4776. cmExpanderBankExecD(p->exb, X1m, p->exb->bandN );
  4777. cmReal_t mean = cmVOR_Mean(X1m,p->exb->bandN);
  4778. cmReal_t arr[3] = { p->exb->rmsValue, mean, p->exb->atkCnt };
  4779. cmVectArrayAppendR(p->oSpecVa,arr,3);
  4780. */
  4781. cmPvSynExec(p->pvs, X1m, p->pva->phsV );
  4782. p->fi += 1;
  4783. }
  4784. return cmOkRC;
  4785. }
  4786. const cmSample_t* cmSpecDistOut( cmSpecDist_t* p )
  4787. {
  4788. return cmPvSynExecOut(p->pvs);
  4789. }
  4790. //------------------------------------------------------------------------------------------------------------
  4791. cmRC_t _cmBinMtxFileWriteHdr( cmBinMtxFile_t* p )
  4792. {
  4793. cmFileRC_t fileRC;
  4794. unsigned n = 3;
  4795. unsigned hdr[n];
  4796. hdr[0] = p->rowCnt;
  4797. hdr[1] = p->maxRowEleCnt;
  4798. hdr[2] = p->eleByteCnt;
  4799. if((fileRC = cmFileSeek(p->fh,kBeginFileFl,0)) != kOkFileRC )
  4800. return cmCtxRtCondition(&p->obj, fileRC, "File seek failed on matrix file:'%s'.", cmStringNullGuard(cmFileName(p->fh)));
  4801. if((fileRC = cmFileWriteUInt(p->fh,hdr,n)) != kOkFileRC )
  4802. return cmCtxRtCondition( &p->obj, fileRC, "Header write failed on matrix file:'%s'.", cmStringNullGuard(cmFileName(p->fh)) );
  4803. return cmOkRC;
  4804. }
  4805. cmBinMtxFile_t* cmBinMtxFileAlloc( cmCtx* ctx, cmBinMtxFile_t* ap, const cmChar_t* fn )
  4806. {
  4807. cmBinMtxFile_t* p = cmObjAlloc( cmBinMtxFile_t, ctx, ap );
  4808. if( fn != NULL )
  4809. if( cmBinMtxFileInit( p, fn ) != cmOkRC )
  4810. cmBinMtxFileFree(&p);
  4811. return p;
  4812. }
  4813. cmRC_t cmBinMtxFileFree( cmBinMtxFile_t** pp )
  4814. {
  4815. cmRC_t rc;
  4816. if( pp==NULL || *pp == NULL )
  4817. return cmOkRC;
  4818. cmBinMtxFile_t* p = *pp;
  4819. if((rc = cmBinMtxFileFinal(p)) == cmOkRC )
  4820. {
  4821. cmObjFree(pp);
  4822. }
  4823. return rc;
  4824. }
  4825. cmRC_t cmBinMtxFileInit( cmBinMtxFile_t* p, const cmChar_t* fn )
  4826. {
  4827. cmRC_t rc;
  4828. cmFileRC_t fileRC;
  4829. if((rc = cmBinMtxFileFinal(p)) != cmOkRC )
  4830. return rc;
  4831. // open the output file for writing
  4832. if((fileRC = cmFileOpen(&p->fh,fn,kWriteFileFl | kBinaryFileFl, p->obj.err.rpt)) != kOkFileRC )
  4833. return cmCtxRtCondition( &p->obj, fileRC, "Unable to open the matrix file:'%s'", cmStringNullGuard(fn) );
  4834. // iniitlaize the object
  4835. p->rowCnt = 0;
  4836. p->maxRowEleCnt = 0;
  4837. p->eleByteCnt = 0;
  4838. // write the blank header as place holder
  4839. if((rc = _cmBinMtxFileWriteHdr(p)) != cmOkRC )
  4840. return rc;
  4841. return rc;
  4842. }
  4843. cmRC_t cmBinMtxFileFinal( cmBinMtxFile_t* p )
  4844. {
  4845. cmRC_t rc;
  4846. cmFileRC_t fileRC;
  4847. if( p != NULL && cmFileIsValid(p->fh))
  4848. {
  4849. // re-write the file header
  4850. if((rc = _cmBinMtxFileWriteHdr(p)) != cmOkRC )
  4851. return rc;
  4852. // close the file
  4853. if((fileRC = cmFileClose(&p->fh)) != kOkFileRC )
  4854. return cmCtxRtCondition(&p->obj, fileRC, "Matrix file close failed on:'%s'",cmStringNullGuard(cmFileName(p->fh)));
  4855. }
  4856. return cmOkRC;
  4857. }
  4858. bool cmBinMtxFileIsValid( cmBinMtxFile_t* p )
  4859. { return p != NULL && cmFileIsValid(p->fh); }
  4860. cmRC_t _cmBinMtxFileWriteRow( cmBinMtxFile_t* p, const void* buf, unsigned eleCnt, unsigned eleByteCnt )
  4861. {
  4862. cmFileRC_t fileRC;
  4863. if((fileRC = cmFileWrite(p->fh,&eleCnt,sizeof(eleCnt))) != kOkFileRC )
  4864. return cmCtxRtCondition(&p->obj, fileRC, "Matrix file row at index %i element count write failed on '%s'.", p->rowCnt, cmStringNullGuard(cmFileName(p->fh)));
  4865. if((fileRC = cmFileWrite(p->fh,buf,eleCnt*eleByteCnt)) != kOkFileRC )
  4866. return cmCtxRtCondition(&p->obj, fileRC, "Matrix file row at index %i data write failed on '%s'.", p->rowCnt, cmStringNullGuard(cmFileName(p->fh)));
  4867. if( eleCnt > p->maxRowEleCnt )
  4868. p->maxRowEleCnt = eleCnt;
  4869. ++p->rowCnt;
  4870. return cmOkRC;
  4871. }
  4872. cmRC_t cmBinMtxFileExecS( cmBinMtxFile_t* p, const cmSample_t* x, unsigned xn )
  4873. {
  4874. // verify that all rows are written as cmSample_t
  4875. assert( p->eleByteCnt == 0 || p->eleByteCnt == sizeof(cmSample_t));
  4876. p->eleByteCnt = sizeof(cmSample_t);
  4877. return _cmBinMtxFileWriteRow(p,x,xn,p->eleByteCnt);
  4878. }
  4879. cmRC_t cmBinMtxFileExecR( cmBinMtxFile_t* p, const cmReal_t* x, unsigned xn )
  4880. {
  4881. // verify that all rows are written as cmReal_t
  4882. assert( p->eleByteCnt == 0 || p->eleByteCnt == sizeof(cmReal_t));
  4883. p->eleByteCnt = sizeof(cmReal_t);
  4884. return _cmBinMtxFileWriteRow(p,x,xn,p->eleByteCnt);
  4885. }
  4886. cmRC_t cmBinMtxFileWrite( const cmChar_t* fn, unsigned rowCnt, unsigned colCnt, const cmSample_t* sp, const cmReal_t* rp, cmCtx* ctx, cmRpt_t* rpt )
  4887. {
  4888. assert( sp == NULL || rp == NULL );
  4889. cmCtx* ctxp = NULL;
  4890. cmBinMtxFile_t* bp = NULL;
  4891. if( ctx == NULL )
  4892. ctx = ctxp = cmCtxAlloc(NULL,rpt,cmLHeapNullHandle,cmSymTblNullHandle);
  4893. if((bp = cmBinMtxFileAlloc(ctx,NULL,fn)) != NULL )
  4894. {
  4895. unsigned i = 0;
  4896. cmSample_t* sbp = sp == NULL ? NULL : cmMemAlloc(cmSample_t,colCnt);
  4897. cmReal_t* rbp = rp == NULL ? NULL : cmMemAlloc(cmReal_t,colCnt);
  4898. for(i=0; i<rowCnt; ++i)
  4899. {
  4900. if( sp!=NULL )
  4901. {
  4902. cmVOS_CopyN(sbp,colCnt,1,sp+i,rowCnt);
  4903. cmBinMtxFileExecS(bp,sbp,colCnt);
  4904. }
  4905. if( rp!=NULL )
  4906. {
  4907. cmVOR_CopyN(rbp,colCnt,1,rp+i,rowCnt);
  4908. cmBinMtxFileExecR(bp,rbp,colCnt);
  4909. }
  4910. }
  4911. cmMemPtrFree(&sbp);
  4912. cmMemPtrFree(&rbp);
  4913. cmBinMtxFileFree(&bp);
  4914. }
  4915. if( ctxp != NULL )
  4916. cmCtxFree(&ctxp);
  4917. return cmOkRC;
  4918. }
  4919. cmRC_t _cmBinMtxFileReadHdr( cmCtx_t* ctx, cmFileH_t h, unsigned* rowCntPtr, unsigned* colCntPtr, unsigned* eleByteCntPtr, const cmChar_t* fn )
  4920. {
  4921. cmRC_t rc = cmOkRC;
  4922. unsigned hdr[3];
  4923. if( cmFileRead(h,&hdr,sizeof(hdr)) != kOkFileRC )
  4924. {
  4925. rc = cmErrMsg(&ctx->err,cmSubSysFailRC,"Binary matrix file header read failed on '%s'.",cmStringNullGuard(fn));
  4926. goto errLabel;
  4927. }
  4928. if( rowCntPtr != NULL )
  4929. *rowCntPtr = hdr[0];
  4930. if( colCntPtr != NULL )
  4931. *colCntPtr = hdr[1];
  4932. if( eleByteCntPtr != NULL )
  4933. *eleByteCntPtr = hdr[2];
  4934. errLabel:
  4935. return rc;
  4936. }
  4937. cmRC_t cmBinMtxFileSize( cmCtx_t* ctx, const cmChar_t* fn, unsigned* rowCntPtr, unsigned* colCntPtr, unsigned* eleByteCntPtr )
  4938. {
  4939. cmFileH_t h = cmFileNullHandle;
  4940. cmRC_t rc = cmOkRC;
  4941. if(cmFileOpen(&h,fn,kReadFileFl | kBinaryFileFl, ctx->err.rpt) != kOkFileRC )
  4942. {
  4943. rc = cmErrMsg(&ctx->err,cmSubSysFailRC,"Binary matrix file:%s open failed.",cmStringNullGuard(fn));
  4944. goto errLabel;
  4945. }
  4946. rc = _cmBinMtxFileReadHdr(ctx,h,rowCntPtr,colCntPtr,eleByteCntPtr,fn);
  4947. errLabel:
  4948. cmFileClose(&h);
  4949. return rc;
  4950. }
  4951. cmRC_t cmBinMtxFileRead( cmCtx_t* ctx, const cmChar_t* fn, unsigned mRowCnt, unsigned mColCnt, unsigned mEleByteCnt, void* retBuf, unsigned* colCntV )
  4952. {
  4953. cmFileH_t h = cmFileNullHandle;
  4954. cmRC_t rc = cmOkRC;
  4955. char* rowBuf = NULL;
  4956. unsigned rowCnt,colCnt,eleByteCnt,i;
  4957. cmErr_t err;
  4958. cmErrSetup(&err,ctx->err.rpt,"Binary Matrix File Reader");
  4959. if(cmFileOpen(&h,fn,kReadFileFl | kBinaryFileFl, err.rpt) != kOkFileRC )
  4960. {
  4961. rc = cmErrMsg(&err,cmSubSysFailRC,"Binary matrix file:%s open failed.",cmStringNullGuard(fn));
  4962. goto errLabel;
  4963. }
  4964. if((rc = _cmBinMtxFileReadHdr(ctx,h,&rowCnt,&colCnt,&eleByteCnt,fn)) != cmOkRC )
  4965. goto errLabel;
  4966. if( mRowCnt != rowCnt )
  4967. rc = cmErrMsg(&err,cmArgAssertRC,"The binary matrix file row count and the return buffer row count are not the same.");
  4968. if( mColCnt != colCnt )
  4969. rc = cmErrMsg(&err,cmArgAssertRC,"The binary matrix file column count and the return buffer column count are not the same.");
  4970. if( mEleByteCnt != eleByteCnt )
  4971. rc = cmErrMsg(&err,cmArgAssertRC,"The binary matrix file element byte count and the return buffer element byte count are not the same.");
  4972. if( rc == cmOkRC )
  4973. {
  4974. rowBuf = cmMemAllocZ(char,colCnt*eleByteCnt);
  4975. for(i=0; i<rowCnt; ++i)
  4976. {
  4977. unsigned cn;
  4978. // read the row length
  4979. if( cmFileReadUInt(h,&cn,1) != kOkFileRC )
  4980. {
  4981. rc = cmErrMsg(&err,cmSubSysFailRC,"Error reading row length at row index:%i.",i);
  4982. goto errLabel;
  4983. }
  4984. if( colCntV != NULL )
  4985. colCntV[i] = cn;
  4986. // verify the actual col count does not exceed the max col count
  4987. if( cn > colCnt )
  4988. {
  4989. rc = cmErrMsg(&err,cmSubSysFailRC,"The actual column count:%i exceeds the max column count:%i.",cn,colCnt);
  4990. goto errLabel;
  4991. }
  4992. //read the row data
  4993. if( cmFileReadChar(h,rowBuf,cn*eleByteCnt) != kOkFileRC )
  4994. {
  4995. rc = cmErrMsg(&err,cmSubSysFailRC,"File read failed at row index:%i.",i);
  4996. goto errLabel;
  4997. }
  4998. char* dp = ((char*)retBuf) + i * eleByteCnt;
  4999. // the data is read in row-major order but the matrix must be
  5000. // returned on col major order - rearrange the columns here.
  5001. switch(eleByteCnt)
  5002. {
  5003. case sizeof(cmSample_t):
  5004. cmVOS_CopyN(((cmSample_t*)dp), cn, rowCnt, (cmSample_t*)rowBuf, 1 );
  5005. break;
  5006. case sizeof(cmReal_t):
  5007. cmVOR_CopyN(((cmReal_t*)dp), cn, rowCnt, (cmReal_t*)rowBuf, 1 );
  5008. break;
  5009. default:
  5010. rc = cmErrMsg(&err,cmSubSysFailRC,"Invalid element byte count:%i.",eleByteCnt);
  5011. goto errLabel;
  5012. }
  5013. }
  5014. }
  5015. errLabel:
  5016. cmMemPtrFree(&rowBuf);
  5017. cmFileClose(&h);
  5018. return rc;
  5019. }