Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CarlaPluginLV2.cpp 308KB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
10 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
6 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
10 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434
  1. /*
  2. * Carla LV2 Plugin
  3. * Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. // testing macros
  18. // #define LV2_UIS_ONLY_BRIDGES
  19. // #define LV2_UIS_ONLY_INPROCESS
  20. #include "CarlaPluginInternal.hpp"
  21. #include "CarlaEngine.hpp"
  22. #include "CarlaLv2Utils.hpp"
  23. #include "CarlaBackendUtils.hpp"
  24. #include "CarlaBase64Utils.hpp"
  25. #include "CarlaEngineUtils.hpp"
  26. #include "CarlaPipeUtils.hpp"
  27. #include "CarlaPluginUI.hpp"
  28. #include "CarlaScopeUtils.hpp"
  29. #include "Lv2AtomRingBuffer.hpp"
  30. #include "../modules/lilv/config/lilv_config.h"
  31. extern "C" {
  32. #include "rtmempool/rtmempool-lv2.h"
  33. }
  34. #include "water/files/File.h"
  35. #include "water/misc/Time.h"
  36. #ifdef CARLA_OS_MAC
  37. # include "CarlaMacUtils.hpp"
  38. # if defined(CARLA_OS_64BIT) && defined(HAVE_LIBMAGIC) && ! defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
  39. # define ADAPT_FOR_APPLE_SILLICON
  40. # include "CarlaBinaryUtils.hpp"
  41. # endif
  42. #endif
  43. #ifdef CARLA_OS_WASM
  44. # define LV2_UIS_ONLY_INPROCESS
  45. #endif
  46. #include <string>
  47. #include <vector>
  48. using water::File;
  49. #define URI_CARLA_ATOM_WORKER_IN "http://kxstudio.sf.net/ns/carla/atomWorkerIn"
  50. #define URI_CARLA_ATOM_WORKER_RESP "http://kxstudio.sf.net/ns/carla/atomWorkerResp"
  51. #define URI_CARLA_PARAMETER_CHANGE "http://kxstudio.sf.net/ns/carla/parameterChange"
  52. CARLA_BACKEND_START_NAMESPACE
  53. // -------------------------------------------------------------------------------------------------------------------
  54. // Fallback data
  55. static const CustomData kCustomDataFallback = { nullptr, nullptr, nullptr };
  56. static /* */ CustomData kCustomDataFallbackNC = { nullptr, nullptr, nullptr };
  57. static const ExternalMidiNote kExternalMidiNoteFallback = { -1, 0, 0 };
  58. static const char* const kUnmapFallback = "urn:null";
  59. // -------------------------------------------------------------------------------------------------------------------
  60. // Maximum default buffer size
  61. const uint MAX_DEFAULT_BUFFER_SIZE = 8192; // 0x2000
  62. // Extra Plugin Hints
  63. const uint PLUGIN_HAS_EXTENSION_OPTIONS = 0x01000;
  64. const uint PLUGIN_HAS_EXTENSION_PROGRAMS = 0x02000;
  65. const uint PLUGIN_HAS_EXTENSION_STATE = 0x04000;
  66. const uint PLUGIN_HAS_EXTENSION_WORKER = 0x08000;
  67. const uint PLUGIN_HAS_EXTENSION_INLINE_DISPLAY = 0x10000;
  68. const uint PLUGIN_HAS_EXTENSION_MIDNAM = 0x20000;
  69. // LV2 Event Data/Types
  70. const uint CARLA_EVENT_DATA_ATOM = 0x01;
  71. const uint CARLA_EVENT_DATA_EVENT = 0x02;
  72. const uint CARLA_EVENT_DATA_MIDI_LL = 0x04;
  73. const uint CARLA_EVENT_TYPE_MESSAGE = 0x10; // unused
  74. const uint CARLA_EVENT_TYPE_MIDI = 0x20;
  75. const uint CARLA_EVENT_TYPE_TIME = 0x40;
  76. // LV2 URI Map Ids
  77. enum CarlaLv2URIDs {
  78. kUridNull = 0,
  79. kUridAtomBlank,
  80. kUridAtomBool,
  81. kUridAtomChunk,
  82. kUridAtomDouble,
  83. kUridAtomEvent,
  84. kUridAtomFloat,
  85. kUridAtomInt,
  86. kUridAtomLiteral,
  87. kUridAtomLong,
  88. kUridAtomNumber,
  89. kUridAtomObject,
  90. kUridAtomPath,
  91. kUridAtomProperty,
  92. kUridAtomResource,
  93. kUridAtomSequence,
  94. kUridAtomSound,
  95. kUridAtomString,
  96. kUridAtomTuple,
  97. kUridAtomURI,
  98. kUridAtomURID,
  99. kUridAtomVector,
  100. kUridAtomTransferAtom,
  101. kUridAtomTransferEvent,
  102. kUridBufMaxLength,
  103. kUridBufMinLength,
  104. kUridBufNominalLength,
  105. kUridBufSequenceSize,
  106. kUridLogError,
  107. kUridLogNote,
  108. kUridLogTrace,
  109. kUridLogWarning,
  110. kUridPatchSet,
  111. kUridPatchProperty,
  112. kUridPatchSubject,
  113. kUridPatchValue,
  114. // time base type
  115. kUridTimePosition,
  116. // time values
  117. kUridTimeBar,
  118. kUridTimeBarBeat,
  119. kUridTimeBeat,
  120. kUridTimeBeatUnit,
  121. kUridTimeBeatsPerBar,
  122. kUridTimeBeatsPerMinute,
  123. kUridTimeFrame,
  124. kUridTimeFramesPerSecond,
  125. kUridTimeSpeed,
  126. kUridTimeTicksPerBeat,
  127. kUridMidiEvent,
  128. kUridParamSampleRate,
  129. // ui stuff
  130. kUridBackgroundColor,
  131. kUridForegroundColor,
  132. #ifndef CARLA_OS_MAC
  133. kUridScaleFactor,
  134. #endif
  135. kUridWindowTitle,
  136. // custom carla props
  137. kUridCarlaAtomWorkerIn,
  138. kUridCarlaAtomWorkerResp,
  139. kUridCarlaParameterChange,
  140. kUridCarlaTransientWindowId,
  141. // count
  142. kUridCount
  143. };
  144. // LV2 Feature Ids
  145. enum CarlaLv2Features {
  146. // DSP features
  147. kFeatureIdBufSizeBounded = 0,
  148. kFeatureIdBufSizeFixed,
  149. kFeatureIdBufSizePowerOf2,
  150. kFeatureIdEvent,
  151. kFeatureIdHardRtCapable,
  152. kFeatureIdInPlaceBroken,
  153. kFeatureIdIsLive,
  154. kFeatureIdLogs,
  155. kFeatureIdOptions,
  156. kFeatureIdPrograms,
  157. kFeatureIdResizePort,
  158. kFeatureIdRtMemPool,
  159. kFeatureIdRtMemPoolOld,
  160. kFeatureIdStateFreePath,
  161. kFeatureIdStateMakePath,
  162. kFeatureIdStateMapPath,
  163. kFeatureIdStrictBounds,
  164. kFeatureIdUriMap,
  165. kFeatureIdUridMap,
  166. kFeatureIdUridUnmap,
  167. kFeatureIdWorker,
  168. kFeatureIdInlineDisplay,
  169. kFeatureIdMidnam,
  170. kFeatureCountPlugin,
  171. // UI features
  172. kFeatureIdUiDataAccess = kFeatureCountPlugin,
  173. kFeatureIdUiInstanceAccess,
  174. kFeatureIdUiIdleInterface,
  175. kFeatureIdUiFixedSize,
  176. kFeatureIdUiMakeResident,
  177. kFeatureIdUiMakeResident2,
  178. kFeatureIdUiNoUserResize,
  179. kFeatureIdUiParent,
  180. kFeatureIdUiPortMap,
  181. kFeatureIdUiPortSubscribe,
  182. kFeatureIdUiResize,
  183. kFeatureIdUiRequestValue,
  184. kFeatureIdUiTouch,
  185. kFeatureIdExternalUi,
  186. kFeatureIdExternalUiOld,
  187. kFeatureCountAll
  188. };
  189. // LV2 Feature Ids (special state handlers)
  190. enum CarlaLv2StateFeatures {
  191. kStateFeatureIdFreePath,
  192. kStateFeatureIdMakePath,
  193. kStateFeatureIdMapPath,
  194. kStateFeatureIdWorker,
  195. kStateFeatureCountAll
  196. };
  197. // -------------------------------------------------------------------------------------------------------------------
  198. struct Lv2EventData {
  199. uint32_t type;
  200. uint32_t rindex;
  201. CarlaEngineEventPort* port;
  202. union {
  203. LV2_Atom_Buffer* atom;
  204. LV2_Event_Buffer* event;
  205. LV2_MIDI midi;
  206. };
  207. Lv2EventData() noexcept
  208. : type(0x0),
  209. rindex(0),
  210. port(nullptr) {}
  211. ~Lv2EventData() noexcept
  212. {
  213. if (port != nullptr)
  214. {
  215. delete port;
  216. port = nullptr;
  217. }
  218. const uint32_t rtype = type;
  219. type = 0x0;
  220. if (rtype & CARLA_EVENT_DATA_ATOM)
  221. {
  222. CARLA_SAFE_ASSERT_RETURN(atom != nullptr,);
  223. std::free(atom);
  224. atom = nullptr;
  225. }
  226. else if (rtype & CARLA_EVENT_DATA_EVENT)
  227. {
  228. CARLA_SAFE_ASSERT_RETURN(event != nullptr,);
  229. std::free(event);
  230. event = nullptr;
  231. }
  232. else if (rtype & CARLA_EVENT_DATA_MIDI_LL)
  233. {
  234. CARLA_SAFE_ASSERT_RETURN(midi.data != nullptr,);
  235. delete[] midi.data;
  236. midi.data = nullptr;
  237. }
  238. }
  239. CARLA_DECLARE_NON_COPYABLE(Lv2EventData)
  240. };
  241. union LV2EventIters {
  242. LV2_Atom_Buffer_Iterator atom;
  243. LV2_Event_Iterator event;
  244. LV2_MIDIState midiState;
  245. };
  246. struct CarlaPluginLV2EventData {
  247. uint32_t count;
  248. Lv2EventData* data;
  249. LV2EventIters* iters;
  250. Lv2EventData* ctrl; // default port, either this->data[x] or pData->portIn/Out
  251. uint32_t ctrlIndex;
  252. CarlaPluginLV2EventData() noexcept
  253. : count(0),
  254. data(nullptr),
  255. iters(nullptr),
  256. ctrl(nullptr),
  257. ctrlIndex(0) {}
  258. ~CarlaPluginLV2EventData() noexcept
  259. {
  260. CARLA_SAFE_ASSERT_INT(count == 0, count);
  261. CARLA_SAFE_ASSERT(data == nullptr);
  262. CARLA_SAFE_ASSERT(iters == nullptr);
  263. CARLA_SAFE_ASSERT(ctrl == nullptr);
  264. CARLA_SAFE_ASSERT_INT(ctrlIndex == 0, ctrlIndex);
  265. }
  266. void createNew(const uint32_t newCount)
  267. {
  268. CARLA_SAFE_ASSERT_INT(count == 0, count);
  269. CARLA_SAFE_ASSERT_INT(ctrlIndex == 0, ctrlIndex);
  270. CARLA_SAFE_ASSERT_RETURN(data == nullptr,);
  271. CARLA_SAFE_ASSERT_RETURN(iters == nullptr,);
  272. CARLA_SAFE_ASSERT_RETURN(ctrl == nullptr,);
  273. CARLA_SAFE_ASSERT_RETURN(newCount > 0,);
  274. data = new Lv2EventData[newCount];
  275. iters = new LV2EventIters[newCount];
  276. count = newCount;
  277. ctrl = nullptr;
  278. ctrlIndex = 0;
  279. }
  280. void clear(CarlaEngineEventPort* const portToIgnore) noexcept
  281. {
  282. if (data != nullptr)
  283. {
  284. for (uint32_t i=0; i < count; ++i)
  285. {
  286. if (data[i].port != nullptr)
  287. {
  288. if (data[i].port != portToIgnore)
  289. delete data[i].port;
  290. data[i].port = nullptr;
  291. }
  292. }
  293. delete[] data;
  294. data = nullptr;
  295. }
  296. if (iters != nullptr)
  297. {
  298. delete[] iters;
  299. iters = nullptr;
  300. }
  301. count = 0;
  302. ctrl = nullptr;
  303. ctrlIndex = 0;
  304. }
  305. void initBuffers() const noexcept
  306. {
  307. for (uint32_t i=0; i < count; ++i)
  308. {
  309. if (data[i].port != nullptr && (ctrl == nullptr || data[i].port != ctrl->port))
  310. data[i].port->initBuffer();
  311. }
  312. }
  313. CARLA_DECLARE_NON_COPYABLE(CarlaPluginLV2EventData)
  314. };
  315. // -------------------------------------------------------------------------------------------------------------------
  316. struct CarlaPluginLV2Options {
  317. enum OptIndex {
  318. MaxBlockLenth = 0,
  319. MinBlockLenth,
  320. NominalBlockLenth,
  321. SequenceSize,
  322. SampleRate,
  323. TransientWinId,
  324. BackgroundColor,
  325. ForegroundColor,
  326. #ifndef CARLA_OS_MAC
  327. ScaleFactor,
  328. #endif
  329. WindowTitle,
  330. Null,
  331. Count
  332. };
  333. int maxBufferSize;
  334. int minBufferSize;
  335. int nominalBufferSize;
  336. int sequenceSize;
  337. float sampleRate;
  338. int64_t transientWinId;
  339. uint32_t bgColor;
  340. uint32_t fgColor;
  341. float uiScale;
  342. const char* windowTitle;
  343. LV2_Options_Option opts[Count];
  344. CarlaPluginLV2Options() noexcept
  345. : maxBufferSize(0),
  346. minBufferSize(0),
  347. nominalBufferSize(0),
  348. sequenceSize(MAX_DEFAULT_BUFFER_SIZE),
  349. sampleRate(0.0),
  350. transientWinId(0),
  351. bgColor(0x000000ff),
  352. fgColor(0xffffffff),
  353. uiScale(1.0f),
  354. windowTitle(nullptr)
  355. {
  356. LV2_Options_Option& optMaxBlockLenth(opts[MaxBlockLenth]);
  357. optMaxBlockLenth.context = LV2_OPTIONS_INSTANCE;
  358. optMaxBlockLenth.subject = 0;
  359. optMaxBlockLenth.key = kUridBufMaxLength;
  360. optMaxBlockLenth.size = sizeof(int);
  361. optMaxBlockLenth.type = kUridAtomInt;
  362. optMaxBlockLenth.value = &maxBufferSize;
  363. LV2_Options_Option& optMinBlockLenth(opts[MinBlockLenth]);
  364. optMinBlockLenth.context = LV2_OPTIONS_INSTANCE;
  365. optMinBlockLenth.subject = 0;
  366. optMinBlockLenth.key = kUridBufMinLength;
  367. optMinBlockLenth.size = sizeof(int);
  368. optMinBlockLenth.type = kUridAtomInt;
  369. optMinBlockLenth.value = &minBufferSize;
  370. LV2_Options_Option& optNominalBlockLenth(opts[NominalBlockLenth]);
  371. optNominalBlockLenth.context = LV2_OPTIONS_INSTANCE;
  372. optNominalBlockLenth.subject = 0;
  373. optNominalBlockLenth.key = kUridBufNominalLength;
  374. optNominalBlockLenth.size = sizeof(int);
  375. optNominalBlockLenth.type = kUridAtomInt;
  376. optNominalBlockLenth.value = &nominalBufferSize;
  377. LV2_Options_Option& optSequenceSize(opts[SequenceSize]);
  378. optSequenceSize.context = LV2_OPTIONS_INSTANCE;
  379. optSequenceSize.subject = 0;
  380. optSequenceSize.key = kUridBufSequenceSize;
  381. optSequenceSize.size = sizeof(int);
  382. optSequenceSize.type = kUridAtomInt;
  383. optSequenceSize.value = &sequenceSize;
  384. LV2_Options_Option& optBackgroundColor(opts[BackgroundColor]);
  385. optBackgroundColor.context = LV2_OPTIONS_INSTANCE;
  386. optBackgroundColor.subject = 0;
  387. optBackgroundColor.key = kUridBackgroundColor;
  388. optBackgroundColor.size = sizeof(int32_t);
  389. optBackgroundColor.type = kUridAtomInt;
  390. optBackgroundColor.value = &bgColor;
  391. LV2_Options_Option& optForegroundColor(opts[ForegroundColor]);
  392. optForegroundColor.context = LV2_OPTIONS_INSTANCE;
  393. optForegroundColor.subject = 0;
  394. optForegroundColor.key = kUridForegroundColor;
  395. optForegroundColor.size = sizeof(int32_t);
  396. optForegroundColor.type = kUridAtomInt;
  397. optForegroundColor.value = &fgColor;
  398. #ifndef CARLA_OS_MAC
  399. LV2_Options_Option& optScaleFactor(opts[ScaleFactor]);
  400. optScaleFactor.context = LV2_OPTIONS_INSTANCE;
  401. optScaleFactor.subject = 0;
  402. optScaleFactor.key = kUridScaleFactor;
  403. optScaleFactor.size = sizeof(float);
  404. optScaleFactor.type = kUridAtomFloat;
  405. optScaleFactor.value = &uiScale;
  406. #endif
  407. LV2_Options_Option& optSampleRate(opts[SampleRate]);
  408. optSampleRate.context = LV2_OPTIONS_INSTANCE;
  409. optSampleRate.subject = 0;
  410. optSampleRate.key = kUridParamSampleRate;
  411. optSampleRate.size = sizeof(float);
  412. optSampleRate.type = kUridAtomFloat;
  413. optSampleRate.value = &sampleRate;
  414. LV2_Options_Option& optTransientWinId(opts[TransientWinId]);
  415. optTransientWinId.context = LV2_OPTIONS_INSTANCE;
  416. optTransientWinId.subject = 0;
  417. optTransientWinId.key = kUridCarlaTransientWindowId;
  418. optTransientWinId.size = sizeof(int64_t);
  419. optTransientWinId.type = kUridAtomLong;
  420. optTransientWinId.value = &transientWinId;
  421. LV2_Options_Option& optWindowTitle(opts[WindowTitle]);
  422. optWindowTitle.context = LV2_OPTIONS_INSTANCE;
  423. optWindowTitle.subject = 0;
  424. optWindowTitle.key = kUridWindowTitle;
  425. optWindowTitle.size = 0;
  426. optWindowTitle.type = kUridAtomString;
  427. optWindowTitle.value = nullptr;
  428. LV2_Options_Option& optNull(opts[Null]);
  429. optNull.context = LV2_OPTIONS_INSTANCE;
  430. optNull.subject = 0;
  431. optNull.key = kUridNull;
  432. optNull.size = 0;
  433. optNull.type = kUridNull;
  434. optNull.value = nullptr;
  435. }
  436. ~CarlaPluginLV2Options() noexcept
  437. {
  438. LV2_Options_Option& optWindowTitle(opts[WindowTitle]);
  439. optWindowTitle.size = 0;
  440. optWindowTitle.value = nullptr;
  441. if (windowTitle != nullptr)
  442. {
  443. std::free(const_cast<char*>(windowTitle));
  444. windowTitle = nullptr;
  445. }
  446. }
  447. CARLA_DECLARE_NON_COPYABLE(CarlaPluginLV2Options);
  448. };
  449. #ifndef LV2_UIS_ONLY_INPROCESS
  450. // -------------------------------------------------------------------------------------------------------------------
  451. class CarlaPluginLV2;
  452. class CarlaPipeServerLV2 : public CarlaPipeServer
  453. {
  454. public:
  455. enum UiState {
  456. UiNone = 0,
  457. UiHide,
  458. UiShow,
  459. UiCrashed
  460. };
  461. CarlaPipeServerLV2(CarlaEngine* const engine, CarlaPluginLV2* const plugin)
  462. : kEngine(engine),
  463. kPlugin(plugin),
  464. fFilename(),
  465. fPluginURI(),
  466. fUiURI(),
  467. fUiState(UiNone) {}
  468. ~CarlaPipeServerLV2() noexcept override
  469. {
  470. CARLA_SAFE_ASSERT_INT(fUiState == UiNone, fUiState);
  471. }
  472. UiState getAndResetUiState() noexcept
  473. {
  474. const UiState uiState(fUiState);
  475. fUiState = UiNone;
  476. return uiState;
  477. }
  478. void setData(const char* const filename, const char* const pluginURI, const char* const uiURI) noexcept
  479. {
  480. fFilename = filename;
  481. fPluginURI = pluginURI;
  482. fUiURI = uiURI;
  483. }
  484. bool startPipeServer(const int size) noexcept
  485. {
  486. char sampleRateStr[32];
  487. {
  488. const CarlaScopedLocale csl;
  489. std::snprintf(sampleRateStr, 31, "%.12g", kEngine->getSampleRate());
  490. }
  491. sampleRateStr[31] = '\0';
  492. const ScopedEngineEnvironmentLocker _seel(kEngine);
  493. const CarlaScopedEnvVar _sev1("LV2_PATH", kEngine->getOptions().pathLV2);
  494. #ifdef CARLA_OS_LINUX
  495. const CarlaScopedEnvVar _sev2("LD_PRELOAD", nullptr);
  496. #endif
  497. carla_setenv("CARLA_SAMPLE_RATE", sampleRateStr);
  498. return CarlaPipeServer::startPipeServer(fFilename, fPluginURI, fUiURI, size);
  499. }
  500. void writeUiTitleMessage(const char* const title) const noexcept
  501. {
  502. CARLA_SAFE_ASSERT_RETURN(title != nullptr && title[0] != '\0',);
  503. const CarlaMutexLocker cml(getPipeLock());
  504. if (! _writeMsgBuffer("uiTitle\n", 8))
  505. return;
  506. if (! writeAndFixMessage(title))
  507. return;
  508. flushMessages();
  509. }
  510. protected:
  511. // returns true if msg was handled
  512. bool msgReceived(const char* const msg) noexcept override;
  513. private:
  514. CarlaEngine* const kEngine;
  515. CarlaPluginLV2* const kPlugin;
  516. CarlaString fFilename;
  517. CarlaString fPluginURI;
  518. CarlaString fUiURI;
  519. UiState fUiState;
  520. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeServerLV2)
  521. };
  522. // -------------------------------------------------------------------------------------------------------------------
  523. #endif
  524. static void initAtomForge(LV2_Atom_Forge& atomForge) noexcept
  525. {
  526. carla_zeroStruct(atomForge);
  527. atomForge.Bool = kUridAtomBool;
  528. atomForge.Chunk = kUridAtomChunk;
  529. atomForge.Double = kUridAtomDouble;
  530. atomForge.Float = kUridAtomFloat;
  531. atomForge.Int = kUridAtomInt;
  532. atomForge.Literal = kUridAtomLiteral;
  533. atomForge.Long = kUridAtomLong;
  534. atomForge.Object = kUridAtomObject;
  535. atomForge.Path = kUridAtomPath;
  536. atomForge.Property = kUridAtomProperty;
  537. atomForge.Sequence = kUridAtomSequence;
  538. atomForge.String = kUridAtomString;
  539. atomForge.Tuple = kUridAtomTuple;
  540. atomForge.URI = kUridAtomURI;
  541. atomForge.URID = kUridAtomURID;
  542. atomForge.Vector = kUridAtomVector;
  543. #if defined(__clang__)
  544. # pragma clang diagnostic push
  545. # pragma clang diagnostic ignored "-Wdeprecated-declarations"
  546. #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
  547. # pragma GCC diagnostic push
  548. # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  549. #endif
  550. atomForge.Blank = kUridAtomBlank;
  551. atomForge.Resource = kUridAtomResource;
  552. #if defined(__clang__)
  553. # pragma clang diagnostic pop
  554. #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
  555. # pragma GCC diagnostic pop
  556. #endif
  557. }
  558. // -------------------------------------------------------------------------------------------------------------------
  559. class CarlaPluginLV2 : public CarlaPlugin,
  560. private CarlaPluginUI::Callback
  561. {
  562. public:
  563. CarlaPluginLV2(CarlaEngine* const engine, const uint id)
  564. : CarlaPlugin(engine, id),
  565. fHandle(nullptr),
  566. fHandle2(nullptr),
  567. fDescriptor(nullptr),
  568. fRdfDescriptor(nullptr),
  569. fAudioInBuffers(nullptr),
  570. fAudioOutBuffers(nullptr),
  571. fCvInBuffers(nullptr),
  572. fCvOutBuffers(nullptr),
  573. fParamBuffers(nullptr),
  574. fHasLoadDefaultState(false),
  575. fHasThreadSafeRestore(false),
  576. fNeedsFixedBuffers(false),
  577. fNeedsUiClose(false),
  578. fInlineDisplayNeedsRedraw(false),
  579. fInlineDisplayLastRedrawTime(0),
  580. fLatencyIndex(-1),
  581. fStrictBounds(-1),
  582. fAtomBufferEvIn(),
  583. fAtomBufferUiOut(),
  584. fAtomBufferWorkerIn(),
  585. fAtomBufferWorkerResp(),
  586. fAtomBufferUiOutTmpData(nullptr),
  587. fAtomBufferWorkerInTmpData(nullptr),
  588. fAtomBufferRealtime(nullptr),
  589. fAtomBufferRealtimeSize(0),
  590. fEventsIn(),
  591. fEventsOut(),
  592. fLv2Options(),
  593. #ifndef LV2_UIS_ONLY_INPROCESS
  594. fPipeServer(engine, this),
  595. #endif
  596. fCustomURIDs(kUridCount, std::string("urn:null")),
  597. fFirstActive(true),
  598. fLastStateChunk(nullptr),
  599. fLastTimeInfo(),
  600. fFilePathURI(),
  601. fExt(),
  602. fUI()
  603. {
  604. carla_debug("CarlaPluginLV2::CarlaPluginLV2(%p, %i)", engine, id);
  605. CARLA_SAFE_ASSERT(fCustomURIDs.size() == kUridCount);
  606. carla_zeroPointers(fFeatures, kFeatureCountAll+1);
  607. carla_zeroPointers(fStateFeatures, kStateFeatureCountAll+1);
  608. }
  609. ~CarlaPluginLV2() override
  610. {
  611. carla_debug("CarlaPluginLV2::~CarlaPluginLV2()");
  612. fInlineDisplayNeedsRedraw = false;
  613. // close UI
  614. if (fUI.type != UI::TYPE_NULL)
  615. {
  616. showCustomUI(false);
  617. #ifndef LV2_UIS_ONLY_INPROCESS
  618. if (fUI.type == UI::TYPE_BRIDGE)
  619. {
  620. fPipeServer.stopPipeServer(pData->engine->getOptions().uiBridgesTimeout);
  621. }
  622. else
  623. #endif
  624. {
  625. if (fFeatures[kFeatureIdUiDataAccess] != nullptr && fFeatures[kFeatureIdUiDataAccess]->data != nullptr)
  626. delete (LV2_Extension_Data_Feature*)fFeatures[kFeatureIdUiDataAccess]->data;
  627. if (fFeatures[kFeatureIdUiPortMap] != nullptr && fFeatures[kFeatureIdUiPortMap]->data != nullptr)
  628. delete (LV2UI_Port_Map*)fFeatures[kFeatureIdUiPortMap]->data;
  629. if (fFeatures[kFeatureIdUiRequestValue] != nullptr && fFeatures[kFeatureIdUiRequestValue]->data != nullptr)
  630. delete (LV2UI_Request_Value*)fFeatures[kFeatureIdUiRequestValue]->data;
  631. if (fFeatures[kFeatureIdUiResize] != nullptr && fFeatures[kFeatureIdUiResize]->data != nullptr)
  632. delete (LV2UI_Resize*)fFeatures[kFeatureIdUiResize]->data;
  633. if (fFeatures[kFeatureIdUiTouch] != nullptr && fFeatures[kFeatureIdUiTouch]->data != nullptr)
  634. delete (LV2UI_Touch*)fFeatures[kFeatureIdUiTouch]->data;
  635. if (fFeatures[kFeatureIdExternalUi] != nullptr && fFeatures[kFeatureIdExternalUi]->data != nullptr)
  636. delete (LV2_External_UI_Host*)fFeatures[kFeatureIdExternalUi]->data;
  637. fUI.descriptor = nullptr;
  638. pData->uiLibClose();
  639. }
  640. #ifndef LV2_UIS_ONLY_BRIDGES
  641. if (fUI.window != nullptr)
  642. {
  643. delete fUI.window;
  644. fUI.window = nullptr;
  645. }
  646. #endif
  647. fUI.rdfDescriptor = nullptr;
  648. }
  649. pData->singleMutex.lock();
  650. pData->masterMutex.lock();
  651. if (pData->client != nullptr && pData->client->isActive())
  652. pData->client->deactivate(true);
  653. if (pData->active)
  654. {
  655. deactivate();
  656. pData->active = false;
  657. }
  658. if (fExt.state != nullptr)
  659. {
  660. const File tmpDir(handleStateMapToAbsolutePath(false, false, true, "."));
  661. if (tmpDir.exists())
  662. tmpDir.deleteRecursively();
  663. }
  664. if (fDescriptor != nullptr)
  665. {
  666. if (fDescriptor->cleanup != nullptr)
  667. {
  668. if (fHandle != nullptr)
  669. fDescriptor->cleanup(fHandle);
  670. if (fHandle2 != nullptr)
  671. fDescriptor->cleanup(fHandle2);
  672. }
  673. fHandle = nullptr;
  674. fHandle2 = nullptr;
  675. fDescriptor = nullptr;
  676. }
  677. if (fRdfDescriptor != nullptr)
  678. {
  679. delete fRdfDescriptor;
  680. fRdfDescriptor = nullptr;
  681. }
  682. if (fFeatures[kFeatureIdEvent] != nullptr && fFeatures[kFeatureIdEvent]->data != nullptr)
  683. delete (LV2_Event_Feature*)fFeatures[kFeatureIdEvent]->data;
  684. if (fFeatures[kFeatureIdLogs] != nullptr && fFeatures[kFeatureIdLogs]->data != nullptr)
  685. delete (LV2_Log_Log*)fFeatures[kFeatureIdLogs]->data;
  686. if (fFeatures[kFeatureIdStateFreePath] != nullptr && fFeatures[kFeatureIdStateFreePath]->data != nullptr)
  687. delete (LV2_State_Free_Path*)fFeatures[kFeatureIdStateFreePath]->data;
  688. if (fFeatures[kFeatureIdStateMakePath] != nullptr && fFeatures[kFeatureIdStateMakePath]->data != nullptr)
  689. delete (LV2_State_Make_Path*)fFeatures[kFeatureIdStateMakePath]->data;
  690. if (fFeatures[kFeatureIdStateMapPath] != nullptr && fFeatures[kFeatureIdStateMapPath]->data != nullptr)
  691. delete (LV2_State_Map_Path*)fFeatures[kFeatureIdStateMapPath]->data;
  692. if (fFeatures[kFeatureIdPrograms] != nullptr && fFeatures[kFeatureIdPrograms]->data != nullptr)
  693. delete (LV2_Programs_Host*)fFeatures[kFeatureIdPrograms]->data;
  694. if (fFeatures[kFeatureIdResizePort] != nullptr && fFeatures[kFeatureIdResizePort]->data != nullptr)
  695. delete (LV2_Resize_Port_Resize*)fFeatures[kFeatureIdResizePort]->data;
  696. if (fFeatures[kFeatureIdRtMemPool] != nullptr && fFeatures[kFeatureIdRtMemPool]->data != nullptr)
  697. delete (LV2_RtMemPool_Pool*)fFeatures[kFeatureIdRtMemPool]->data;
  698. if (fFeatures[kFeatureIdRtMemPoolOld] != nullptr && fFeatures[kFeatureIdRtMemPoolOld]->data != nullptr)
  699. delete (LV2_RtMemPool_Pool_Deprecated*)fFeatures[kFeatureIdRtMemPoolOld]->data;
  700. if (fFeatures[kFeatureIdUriMap] != nullptr && fFeatures[kFeatureIdUriMap]->data != nullptr)
  701. delete (LV2_URI_Map_Feature*)fFeatures[kFeatureIdUriMap]->data;
  702. if (fFeatures[kFeatureIdUridMap] != nullptr && fFeatures[kFeatureIdUridMap]->data != nullptr)
  703. delete (LV2_URID_Map*)fFeatures[kFeatureIdUridMap]->data;
  704. if (fFeatures[kFeatureIdUridUnmap] != nullptr && fFeatures[kFeatureIdUridUnmap]->data != nullptr)
  705. delete (LV2_URID_Unmap*)fFeatures[kFeatureIdUridUnmap]->data;
  706. if (fFeatures[kFeatureIdWorker] != nullptr && fFeatures[kFeatureIdWorker]->data != nullptr)
  707. delete (LV2_Worker_Schedule*)fFeatures[kFeatureIdWorker]->data;
  708. if (fFeatures[kFeatureIdInlineDisplay] != nullptr && fFeatures[kFeatureIdInlineDisplay]->data != nullptr)
  709. delete (LV2_Inline_Display*)fFeatures[kFeatureIdInlineDisplay]->data;
  710. if (fFeatures[kFeatureIdMidnam] != nullptr && fFeatures[kFeatureIdMidnam]->data != nullptr)
  711. delete (LV2_Midnam*)fFeatures[kFeatureIdMidnam]->data;
  712. for (uint32_t i=0; i < kFeatureCountAll; ++i)
  713. {
  714. if (fFeatures[i] != nullptr)
  715. {
  716. delete fFeatures[i];
  717. fFeatures[i] = nullptr;
  718. }
  719. }
  720. if (fStateFeatures[kStateFeatureIdMakePath] != nullptr && fStateFeatures[kStateFeatureIdMakePath]->data != nullptr)
  721. delete (LV2_State_Make_Path*)fStateFeatures[kStateFeatureIdMakePath]->data;
  722. if (fStateFeatures[kStateFeatureIdMapPath] != nullptr && fStateFeatures[kStateFeatureIdMapPath]->data != nullptr)
  723. delete (LV2_State_Map_Path*)fStateFeatures[kStateFeatureIdMapPath]->data;
  724. for (uint32_t i=0; i < kStateFeatureCountAll; ++i)
  725. {
  726. if (fStateFeatures[i] != nullptr)
  727. {
  728. delete fStateFeatures[i];
  729. fStateFeatures[i] = nullptr;
  730. }
  731. }
  732. if (fLastStateChunk != nullptr)
  733. {
  734. std::free(fLastStateChunk);
  735. fLastStateChunk = nullptr;
  736. }
  737. if (fAtomBufferUiOutTmpData != nullptr)
  738. {
  739. delete[] fAtomBufferUiOutTmpData;
  740. fAtomBufferUiOutTmpData = nullptr;
  741. }
  742. if (fAtomBufferWorkerInTmpData != nullptr)
  743. {
  744. delete[] fAtomBufferWorkerInTmpData;
  745. fAtomBufferWorkerInTmpData = nullptr;
  746. }
  747. if (fAtomBufferRealtime != nullptr)
  748. {
  749. std::free(fAtomBufferRealtime);
  750. fAtomBufferRealtime = nullptr;
  751. }
  752. clearBuffers();
  753. }
  754. // -------------------------------------------------------------------
  755. // Information (base)
  756. PluginType getType() const noexcept override
  757. {
  758. return PLUGIN_LV2;
  759. }
  760. PluginCategory getCategory() const noexcept override
  761. {
  762. CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, CarlaPlugin::getCategory());
  763. const LV2_Property cat1(fRdfDescriptor->Type[0]);
  764. const LV2_Property cat2(fRdfDescriptor->Type[1]);
  765. if (LV2_IS_DELAY(cat1, cat2))
  766. return PLUGIN_CATEGORY_DELAY;
  767. if (LV2_IS_DISTORTION(cat1, cat2))
  768. return PLUGIN_CATEGORY_OTHER;
  769. if (LV2_IS_DYNAMICS(cat1, cat2))
  770. return PLUGIN_CATEGORY_DYNAMICS;
  771. if (LV2_IS_EQ(cat1, cat2))
  772. return PLUGIN_CATEGORY_EQ;
  773. if (LV2_IS_FILTER(cat1, cat2))
  774. return PLUGIN_CATEGORY_FILTER;
  775. if (LV2_IS_GENERATOR(cat1, cat2))
  776. return PLUGIN_CATEGORY_SYNTH;
  777. if (LV2_IS_MODULATOR(cat1, cat2))
  778. return PLUGIN_CATEGORY_MODULATOR;
  779. if (LV2_IS_REVERB(cat1, cat2))
  780. return PLUGIN_CATEGORY_DELAY;
  781. if (LV2_IS_SIMULATOR(cat1, cat2))
  782. return PLUGIN_CATEGORY_OTHER;
  783. if (LV2_IS_SPATIAL(cat1, cat2))
  784. return PLUGIN_CATEGORY_OTHER;
  785. if (LV2_IS_SPECTRAL(cat1, cat2))
  786. return PLUGIN_CATEGORY_UTILITY;
  787. if (LV2_IS_UTILITY(cat1, cat2))
  788. return PLUGIN_CATEGORY_UTILITY;
  789. return CarlaPlugin::getCategory();
  790. }
  791. uint32_t getLatencyInFrames() const noexcept override
  792. {
  793. if (fLatencyIndex < 0 || fParamBuffers == nullptr)
  794. return 0;
  795. const float latency(fParamBuffers[fLatencyIndex]);
  796. CARLA_SAFE_ASSERT_RETURN(latency >= 0.0f, 0);
  797. return static_cast<uint32_t>(latency);
  798. }
  799. // -------------------------------------------------------------------
  800. // Information (count)
  801. uint32_t getMidiInCount() const noexcept override
  802. {
  803. CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, 0);
  804. uint32_t count = 0;
  805. for (uint32_t i=0; i < fRdfDescriptor->PortCount; ++i)
  806. {
  807. const LV2_Property portTypes(fRdfDescriptor->Ports[i].Types);
  808. if (LV2_IS_PORT_INPUT(portTypes) && LV2_PORT_SUPPORTS_MIDI_EVENT(portTypes))
  809. ++count;
  810. }
  811. return count;
  812. }
  813. uint32_t getMidiOutCount() const noexcept override
  814. {
  815. CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, 0);
  816. uint32_t count = 0;
  817. for (uint32_t i=0; i < fRdfDescriptor->PortCount; ++i)
  818. {
  819. const LV2_Property portTypes(fRdfDescriptor->Ports[i].Types);
  820. if (LV2_IS_PORT_OUTPUT(portTypes) && LV2_PORT_SUPPORTS_MIDI_EVENT(portTypes))
  821. ++count;
  822. }
  823. return count;
  824. }
  825. uint32_t getParameterScalePointCount(const uint32_t parameterId) const noexcept override
  826. {
  827. CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, 0);
  828. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0);
  829. const int32_t rindex(pData->param.data[parameterId].rindex);
  830. if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
  831. {
  832. const LV2_RDF_Port* const port(&fRdfDescriptor->Ports[rindex]);
  833. return port->ScalePointCount;
  834. }
  835. return 0;
  836. }
  837. // -------------------------------------------------------------------
  838. // Information (current data)
  839. uint getAudioPortHints(bool isOutput, uint32_t portIndex) const noexcept override
  840. {
  841. uint hints = 0x0;
  842. for (uint32_t i=0, j=0; i<fRdfDescriptor->PortCount; ++i)
  843. {
  844. LV2_RDF_Port& port(fRdfDescriptor->Ports[i]);
  845. if (! LV2_IS_PORT_AUDIO(port.Types))
  846. continue;
  847. if (isOutput)
  848. {
  849. if (! LV2_IS_PORT_OUTPUT(port.Types))
  850. continue;
  851. }
  852. else
  853. {
  854. if (! LV2_IS_PORT_INPUT(port.Types))
  855. continue;
  856. }
  857. if (j++ != portIndex)
  858. continue;
  859. if (LV2_IS_PORT_SIDECHAIN(port.Properties))
  860. hints |= AUDIO_PORT_IS_SIDECHAIN;
  861. break;
  862. }
  863. return hints;
  864. }
  865. // -------------------------------------------------------------------
  866. // Information (per-plugin data)
  867. uint getOptionsAvailable() const noexcept override
  868. {
  869. uint options = 0x0;
  870. // can't disable fixed buffers if using latency or MIDI output
  871. if (fLatencyIndex == -1 && getMidiOutCount() == 0 && ! fNeedsFixedBuffers)
  872. options |= PLUGIN_OPTION_FIXED_BUFFERS;
  873. // can't disable forced stereo if enabled in the engine
  874. if (pData->engine->getOptions().forceStereo)
  875. pass();
  876. // if there are event outputs, we can't force stereo
  877. else if (fEventsOut.count != 0)
  878. pass();
  879. // if inputs or outputs are just 1, then yes we can force stereo
  880. else if ((pData->audioIn.count == 1 || pData->audioOut.count == 1) || fHandle2 != nullptr)
  881. options |= PLUGIN_OPTION_FORCE_STEREO;
  882. if (fExt.programs != nullptr)
  883. options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  884. if (getMidiInCount() != 0)
  885. {
  886. options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  887. options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  888. options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  889. options |= PLUGIN_OPTION_SEND_PITCHBEND;
  890. options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  891. options |= PLUGIN_OPTION_SEND_PROGRAM_CHANGES;
  892. options |= PLUGIN_OPTION_SKIP_SENDING_NOTES;
  893. }
  894. return options;
  895. }
  896. float getParameterValue(const uint32_t parameterId) const noexcept override
  897. {
  898. CARLA_SAFE_ASSERT_RETURN(fParamBuffers != nullptr, 0.0f);
  899. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0.0f);
  900. if (pData->param.data[parameterId].type == PARAMETER_INPUT)
  901. {
  902. if (pData->param.data[parameterId].hints & PARAMETER_IS_STRICT_BOUNDS)
  903. pData->param.ranges[parameterId].fixValue(fParamBuffers[parameterId]);
  904. }
  905. else
  906. {
  907. if (fStrictBounds >= 0 && (pData->param.data[parameterId].hints & PARAMETER_IS_STRICT_BOUNDS) == 0)
  908. pData->param.ranges[parameterId].fixValue(fParamBuffers[parameterId]);
  909. }
  910. return fParamBuffers[parameterId];
  911. }
  912. float getParameterScalePointValue(const uint32_t parameterId, const uint32_t scalePointId) const noexcept override
  913. {
  914. CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, 0.0f);
  915. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0.0f);
  916. const int32_t rindex(pData->param.data[parameterId].rindex);
  917. if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
  918. {
  919. const LV2_RDF_Port* const port(&fRdfDescriptor->Ports[rindex]);
  920. CARLA_SAFE_ASSERT_RETURN(scalePointId < port->ScalePointCount, 0.0f);
  921. const LV2_RDF_PortScalePoint* const portScalePoint(&port->ScalePoints[scalePointId]);
  922. return portScalePoint->Value;
  923. }
  924. return 0.0f;
  925. }
  926. bool getLabel(char* const strBuf) const noexcept override
  927. {
  928. CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
  929. CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor->URI != nullptr, false);
  930. std::strncpy(strBuf, fRdfDescriptor->URI, STR_MAX);
  931. return true;
  932. }
  933. bool getMaker(char* const strBuf) const noexcept override
  934. {
  935. CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
  936. if (fRdfDescriptor->Author != nullptr)
  937. {
  938. std::strncpy(strBuf, fRdfDescriptor->Author, STR_MAX);
  939. return true;
  940. }
  941. return false;
  942. }
  943. bool getCopyright(char* const strBuf) const noexcept override
  944. {
  945. CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
  946. if (fRdfDescriptor->License != nullptr)
  947. {
  948. std::strncpy(strBuf, fRdfDescriptor->License, STR_MAX);
  949. return true;
  950. }
  951. return false;
  952. }
  953. bool getRealName(char* const strBuf) const noexcept override
  954. {
  955. CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
  956. if (fRdfDescriptor->Name != nullptr)
  957. {
  958. std::strncpy(strBuf, fRdfDescriptor->Name, STR_MAX);
  959. return true;
  960. }
  961. return false;
  962. }
  963. bool getParameterName(const uint32_t parameterId, char* const strBuf) const noexcept override
  964. {
  965. CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
  966. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
  967. int32_t rindex = pData->param.data[parameterId].rindex;
  968. CARLA_SAFE_ASSERT_RETURN(rindex >= 0, false);
  969. if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
  970. {
  971. std::strncpy(strBuf, fRdfDescriptor->Ports[rindex].Name, STR_MAX);
  972. return true;
  973. }
  974. rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount);
  975. if (rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount))
  976. {
  977. std::strncpy(strBuf, fRdfDescriptor->Parameters[rindex].Label, STR_MAX);
  978. return true;
  979. }
  980. return CarlaPlugin::getParameterName(parameterId, strBuf);
  981. }
  982. bool getParameterSymbol(const uint32_t parameterId, char* const strBuf) const noexcept override
  983. {
  984. CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
  985. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
  986. int32_t rindex = pData->param.data[parameterId].rindex;
  987. CARLA_SAFE_ASSERT_RETURN(rindex >= 0, false);
  988. if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
  989. {
  990. std::strncpy(strBuf, fRdfDescriptor->Ports[rindex].Symbol, STR_MAX);
  991. return true;
  992. }
  993. rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount);
  994. if (rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount))
  995. {
  996. std::strncpy(strBuf, fRdfDescriptor->Parameters[rindex].URI, STR_MAX);
  997. return true;
  998. }
  999. return CarlaPlugin::getParameterSymbol(parameterId, strBuf);
  1000. }
  1001. bool getParameterUnit(const uint32_t parameterId, char* const strBuf) const noexcept override
  1002. {
  1003. CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
  1004. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
  1005. LV2_RDF_PortUnit* portUnit = nullptr;
  1006. int32_t rindex = pData->param.data[parameterId].rindex;
  1007. CARLA_SAFE_ASSERT_RETURN(rindex >= 0, false);
  1008. if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
  1009. {
  1010. portUnit = &fRdfDescriptor->Ports[rindex].Unit;
  1011. }
  1012. else
  1013. {
  1014. rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount);
  1015. if (rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount))
  1016. {
  1017. portUnit = &fRdfDescriptor->Parameters[rindex].Unit;
  1018. }
  1019. }
  1020. if (portUnit != nullptr)
  1021. {
  1022. if (LV2_HAVE_PORT_UNIT_SYMBOL(portUnit->Hints) && portUnit->Symbol != nullptr)
  1023. {
  1024. std::strncpy(strBuf, portUnit->Symbol, STR_MAX);
  1025. return true;
  1026. }
  1027. if (LV2_HAVE_PORT_UNIT_UNIT(portUnit->Hints))
  1028. {
  1029. switch (portUnit->Unit)
  1030. {
  1031. case LV2_PORT_UNIT_BAR:
  1032. std::strncpy(strBuf, "bars", STR_MAX);
  1033. return true;
  1034. case LV2_PORT_UNIT_BEAT:
  1035. std::strncpy(strBuf, "beats", STR_MAX);
  1036. return true;
  1037. case LV2_PORT_UNIT_BPM:
  1038. std::strncpy(strBuf, "BPM", STR_MAX);
  1039. return true;
  1040. case LV2_PORT_UNIT_CENT:
  1041. std::strncpy(strBuf, "ct", STR_MAX);
  1042. return true;
  1043. case LV2_PORT_UNIT_CM:
  1044. std::strncpy(strBuf, "cm", STR_MAX);
  1045. return true;
  1046. case LV2_PORT_UNIT_COEF:
  1047. std::strncpy(strBuf, "(coef)", STR_MAX);
  1048. return true;
  1049. case LV2_PORT_UNIT_DB:
  1050. std::strncpy(strBuf, "dB", STR_MAX);
  1051. return true;
  1052. case LV2_PORT_UNIT_DEGREE:
  1053. std::strncpy(strBuf, "deg", STR_MAX);
  1054. return true;
  1055. case LV2_PORT_UNIT_FRAME:
  1056. std::strncpy(strBuf, "frames", STR_MAX);
  1057. return true;
  1058. case LV2_PORT_UNIT_HZ:
  1059. std::strncpy(strBuf, "Hz", STR_MAX);
  1060. return true;
  1061. case LV2_PORT_UNIT_INCH:
  1062. std::strncpy(strBuf, "in", STR_MAX);
  1063. return true;
  1064. case LV2_PORT_UNIT_KHZ:
  1065. std::strncpy(strBuf, "kHz", STR_MAX);
  1066. return true;
  1067. case LV2_PORT_UNIT_KM:
  1068. std::strncpy(strBuf, "km", STR_MAX);
  1069. return true;
  1070. case LV2_PORT_UNIT_M:
  1071. std::strncpy(strBuf, "m", STR_MAX);
  1072. return true;
  1073. case LV2_PORT_UNIT_MHZ:
  1074. std::strncpy(strBuf, "MHz", STR_MAX);
  1075. return true;
  1076. case LV2_PORT_UNIT_MIDINOTE:
  1077. std::strncpy(strBuf, "note", STR_MAX);
  1078. return true;
  1079. case LV2_PORT_UNIT_MILE:
  1080. std::strncpy(strBuf, "mi", STR_MAX);
  1081. return true;
  1082. case LV2_PORT_UNIT_MIN:
  1083. std::strncpy(strBuf, "min", STR_MAX);
  1084. return true;
  1085. case LV2_PORT_UNIT_MM:
  1086. std::strncpy(strBuf, "mm", STR_MAX);
  1087. return true;
  1088. case LV2_PORT_UNIT_MS:
  1089. std::strncpy(strBuf, "ms", STR_MAX);
  1090. return true;
  1091. case LV2_PORT_UNIT_OCT:
  1092. std::strncpy(strBuf, "oct", STR_MAX);
  1093. return true;
  1094. case LV2_PORT_UNIT_PC:
  1095. std::strncpy(strBuf, "%", STR_MAX);
  1096. return true;
  1097. case LV2_PORT_UNIT_S:
  1098. std::strncpy(strBuf, "s", STR_MAX);
  1099. return true;
  1100. case LV2_PORT_UNIT_SEMITONE:
  1101. std::strncpy(strBuf, "semi", STR_MAX);
  1102. return true;
  1103. case LV2_PORT_UNIT_VOLTS:
  1104. std::strncpy(strBuf, "v", STR_MAX);
  1105. return true;
  1106. }
  1107. }
  1108. }
  1109. return CarlaPlugin::getParameterUnit(parameterId, strBuf);
  1110. }
  1111. bool getParameterComment(const uint32_t parameterId, char* const strBuf) const noexcept override
  1112. {
  1113. CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
  1114. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
  1115. int32_t rindex = pData->param.data[parameterId].rindex;
  1116. CARLA_SAFE_ASSERT_RETURN(rindex >= 0, false);
  1117. if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
  1118. {
  1119. if (const char* const comment = fRdfDescriptor->Ports[rindex].Comment)
  1120. {
  1121. std::strncpy(strBuf, comment, STR_MAX);
  1122. return true;
  1123. }
  1124. return false;
  1125. }
  1126. rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount);
  1127. if (rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount))
  1128. {
  1129. if (const char* const comment = fRdfDescriptor->Parameters[rindex].Comment)
  1130. {
  1131. std::strncpy(strBuf, comment, STR_MAX);
  1132. return true;
  1133. }
  1134. return false;
  1135. }
  1136. return CarlaPlugin::getParameterComment(parameterId, strBuf);
  1137. }
  1138. bool getParameterGroupName(const uint32_t parameterId, char* const strBuf) const noexcept override
  1139. {
  1140. CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
  1141. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
  1142. int32_t rindex = pData->param.data[parameterId].rindex;
  1143. CARLA_SAFE_ASSERT_RETURN(rindex >= 0, false);
  1144. const char* uri = nullptr;
  1145. if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
  1146. {
  1147. uri = fRdfDescriptor->Ports[rindex].GroupURI;
  1148. }
  1149. else
  1150. {
  1151. rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount);
  1152. if (rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount))
  1153. uri = fRdfDescriptor->Parameters[rindex].GroupURI;
  1154. }
  1155. if (uri == nullptr)
  1156. return false;
  1157. for (uint32_t i=0; i<fRdfDescriptor->PortGroupCount; ++i)
  1158. {
  1159. if (std::strcmp(fRdfDescriptor->PortGroups[i].URI, uri) == 0)
  1160. {
  1161. const char* const name = fRdfDescriptor->PortGroups[i].Name;
  1162. const char* const symbol = fRdfDescriptor->PortGroups[i].Symbol;
  1163. if (name != nullptr && symbol != nullptr)
  1164. {
  1165. std::snprintf(strBuf, STR_MAX, "%s:%s", symbol, name);
  1166. return true;
  1167. }
  1168. return false;
  1169. }
  1170. }
  1171. return false;
  1172. }
  1173. bool getParameterScalePointLabel(const uint32_t parameterId, const uint32_t scalePointId, char* const strBuf) const noexcept override
  1174. {
  1175. CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
  1176. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
  1177. const int32_t rindex(pData->param.data[parameterId].rindex);
  1178. CARLA_SAFE_ASSERT_RETURN(rindex >= 0, false);
  1179. if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
  1180. {
  1181. const LV2_RDF_Port* const port(&fRdfDescriptor->Ports[rindex]);
  1182. CARLA_SAFE_ASSERT_RETURN(scalePointId < port->ScalePointCount, false);
  1183. const LV2_RDF_PortScalePoint* const portScalePoint(&port->ScalePoints[scalePointId]);
  1184. if (portScalePoint->Label != nullptr)
  1185. {
  1186. std::strncpy(strBuf, portScalePoint->Label, STR_MAX);
  1187. return true;
  1188. }
  1189. }
  1190. return CarlaPlugin::getParameterScalePointLabel(parameterId, scalePointId, strBuf);
  1191. }
  1192. // -------------------------------------------------------------------
  1193. // Set data (state)
  1194. void prepareForSave(const bool temporary) override
  1195. {
  1196. CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
  1197. if (fExt.state != nullptr && fExt.state->save != nullptr)
  1198. {
  1199. // move temporary stuff to main state dir on full save
  1200. if (! temporary)
  1201. {
  1202. const File tmpDir(handleStateMapToAbsolutePath(false, false, true, "."));
  1203. if (tmpDir.exists())
  1204. {
  1205. const File stateDir(handleStateMapToAbsolutePath(true, false, false, "."));
  1206. if (stateDir.isNotNull())
  1207. tmpDir.moveFileTo(stateDir);
  1208. }
  1209. }
  1210. fExt.state->save(fHandle, carla_lv2_state_store, this, LV2_STATE_IS_POD, fStateFeatures);
  1211. if (fHandle2 != nullptr)
  1212. fExt.state->save(fHandle2, carla_lv2_state_store, this, LV2_STATE_IS_POD, fStateFeatures);
  1213. }
  1214. }
  1215. // -------------------------------------------------------------------
  1216. // Set data (internal stuff)
  1217. void setName(const char* const newName) override
  1218. {
  1219. const File tmpDir1(handleStateMapToAbsolutePath(false, false, true, "."));
  1220. CarlaPlugin::setName(newName);
  1221. if (tmpDir1.exists())
  1222. {
  1223. const File tmpDir2(handleStateMapToAbsolutePath(false, false, true, "."));
  1224. carla_stdout("dir1 %s, dir2 %s",
  1225. tmpDir1.getFullPathName().toRawUTF8(),
  1226. tmpDir2.getFullPathName().toRawUTF8());
  1227. if (tmpDir2.isNotNull())
  1228. {
  1229. if (tmpDir2.exists())
  1230. tmpDir2.deleteRecursively();
  1231. tmpDir1.moveFileTo(tmpDir2);
  1232. }
  1233. }
  1234. if (fLv2Options.windowTitle != nullptr && pData->uiTitle.isEmpty())
  1235. setWindowTitle(nullptr);
  1236. }
  1237. void setWindowTitle(const char* const title) noexcept
  1238. {
  1239. CarlaString uiTitle;
  1240. if (title != nullptr)
  1241. {
  1242. uiTitle = title;
  1243. }
  1244. else
  1245. {
  1246. uiTitle = pData->name;
  1247. uiTitle += " (GUI)";
  1248. }
  1249. std::free(const_cast<char*>(fLv2Options.windowTitle));
  1250. fLv2Options.windowTitle = uiTitle.releaseBufferPointer();
  1251. fLv2Options.opts[CarlaPluginLV2Options::WindowTitle].size = (uint32_t)std::strlen(fLv2Options.windowTitle);
  1252. fLv2Options.opts[CarlaPluginLV2Options::WindowTitle].value = fLv2Options.windowTitle;
  1253. if (fFeatures[kFeatureIdExternalUi] != nullptr && fFeatures[kFeatureIdExternalUi]->data != nullptr)
  1254. ((LV2_External_UI_Host*)fFeatures[kFeatureIdExternalUi]->data)->plugin_human_id = fLv2Options.windowTitle;
  1255. #ifndef LV2_UIS_ONLY_INPROCESS
  1256. if (fPipeServer.isPipeRunning())
  1257. fPipeServer.writeUiTitleMessage(fLv2Options.windowTitle);
  1258. #endif
  1259. #ifndef LV2_UIS_ONLY_BRIDGES
  1260. if (fUI.window != nullptr)
  1261. {
  1262. try {
  1263. fUI.window->setTitle(fLv2Options.windowTitle);
  1264. } CARLA_SAFE_EXCEPTION("set custom title");
  1265. }
  1266. #endif
  1267. }
  1268. // -------------------------------------------------------------------
  1269. // Set data (plugin-specific stuff)
  1270. float setParamterValueCommon(const uint32_t parameterId, const float value) noexcept
  1271. {
  1272. const float fixedValue(pData->param.getFixedValue(parameterId, value));
  1273. fParamBuffers[parameterId] = fixedValue;
  1274. if (pData->param.data[parameterId].rindex >= static_cast<int32_t>(fRdfDescriptor->PortCount))
  1275. {
  1276. const uint32_t rparamId = static_cast<uint32_t>(pData->param.data[parameterId].rindex) - fRdfDescriptor->PortCount;
  1277. CARLA_SAFE_ASSERT_UINT2_RETURN(rparamId < fRdfDescriptor->ParameterCount,
  1278. rparamId, fRdfDescriptor->PortCount, fixedValue);
  1279. uint8_t atomBuf[256];
  1280. LV2_Atom_Forge atomForge;
  1281. initAtomForge(atomForge);
  1282. lv2_atom_forge_set_buffer(&atomForge, atomBuf, sizeof(atomBuf));
  1283. LV2_Atom_Forge_Frame forgeFrame;
  1284. lv2_atom_forge_object(&atomForge, &forgeFrame, kUridNull, kUridPatchSet);
  1285. lv2_atom_forge_key(&atomForge, kUridCarlaParameterChange);
  1286. lv2_atom_forge_bool(&atomForge, true);
  1287. lv2_atom_forge_key(&atomForge, kUridPatchProperty);
  1288. lv2_atom_forge_urid(&atomForge, getCustomURID(fRdfDescriptor->Parameters[rparamId].URI));
  1289. lv2_atom_forge_key(&atomForge, kUridPatchValue);
  1290. switch (fRdfDescriptor->Parameters[rparamId].Type)
  1291. {
  1292. case LV2_PARAMETER_TYPE_BOOL:
  1293. lv2_atom_forge_bool(&atomForge, fixedValue > 0.5f);
  1294. break;
  1295. case LV2_PARAMETER_TYPE_INT:
  1296. lv2_atom_forge_int(&atomForge, static_cast<int32_t>(fixedValue + 0.5f));
  1297. break;
  1298. case LV2_PARAMETER_TYPE_LONG:
  1299. lv2_atom_forge_long(&atomForge, static_cast<int64_t>(fixedValue + 0.5f));
  1300. break;
  1301. case LV2_PARAMETER_TYPE_FLOAT:
  1302. lv2_atom_forge_float(&atomForge, fixedValue);
  1303. break;
  1304. case LV2_PARAMETER_TYPE_DOUBLE:
  1305. lv2_atom_forge_double(&atomForge, fixedValue);
  1306. break;
  1307. default:
  1308. carla_stderr2("setParameterValue called for invalid parameter, expect issues!");
  1309. break;
  1310. }
  1311. lv2_atom_forge_pop(&atomForge, &forgeFrame);
  1312. LV2_Atom* const atom((LV2_Atom*)atomBuf);
  1313. CARLA_SAFE_ASSERT(atom->size < sizeof(atomBuf));
  1314. fAtomBufferEvIn.put(atom, fEventsIn.ctrlIndex);
  1315. }
  1316. return fixedValue;
  1317. }
  1318. void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override
  1319. {
  1320. CARLA_SAFE_ASSERT_RETURN(fParamBuffers != nullptr,);
  1321. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  1322. const float fixedValue = setParamterValueCommon(parameterId, value);
  1323. CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback);
  1324. }
  1325. void setParameterValueRT(const uint32_t parameterId, const float value, const uint32_t frameOffset, const bool sendCallbackLater) noexcept override
  1326. {
  1327. CARLA_SAFE_ASSERT_RETURN(fParamBuffers != nullptr,);
  1328. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  1329. const float fixedValue = setParamterValueCommon(parameterId, value);
  1330. CarlaPlugin::setParameterValueRT(parameterId, fixedValue, frameOffset, sendCallbackLater);
  1331. }
  1332. void setCustomData(const char* const type, const char* const key, const char* const value, const bool sendGui) override
  1333. {
  1334. CARLA_SAFE_ASSERT_RETURN(fDescriptor != nullptr,);
  1335. CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
  1336. CARLA_SAFE_ASSERT_RETURN(type != nullptr && type[0] != '\0',);
  1337. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  1338. CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
  1339. carla_debug("CarlaPluginLV2::setCustomData(\"%s\", \"%s\", \"%s\", %s)", type, key, value, bool2str(sendGui));
  1340. if (std::strcmp(type, CUSTOM_DATA_TYPE_PATH) == 0)
  1341. {
  1342. if (std::strcmp(key, "file") != 0)
  1343. return;
  1344. CARLA_SAFE_ASSERT_RETURN(fFilePathURI.isNotEmpty(),);
  1345. CARLA_SAFE_ASSERT_RETURN(value[0] != '\0',);
  1346. carla_stdout("LV2 file path to send: '%s'", value);
  1347. writeAtomPath(value, getCustomURID(fFilePathURI));
  1348. return;
  1349. }
  1350. if (std::strcmp(type, CUSTOM_DATA_TYPE_PROPERTY) == 0)
  1351. return CarlaPlugin::setCustomData(type, key, value, sendGui);
  1352. // See if this key is from a parameter exposed by carla, apply value if yes
  1353. for (uint32_t i=0; i < fRdfDescriptor->ParameterCount; ++i)
  1354. {
  1355. const LV2_RDF_Parameter& rdfParam(fRdfDescriptor->Parameters[i]);
  1356. if (std::strcmp(rdfParam.URI, key) == 0)
  1357. {
  1358. uint32_t parameterId = UINT32_MAX;
  1359. const int32_t rindex = static_cast<int32_t>(fRdfDescriptor->PortCount + i);
  1360. switch (rdfParam.Type)
  1361. {
  1362. case LV2_PARAMETER_TYPE_BOOL:
  1363. case LV2_PARAMETER_TYPE_INT:
  1364. // case LV2_PARAMETER_TYPE_LONG:
  1365. case LV2_PARAMETER_TYPE_FLOAT:
  1366. case LV2_PARAMETER_TYPE_DOUBLE:
  1367. for (uint32_t j=0; j < pData->param.count; ++j)
  1368. {
  1369. if (pData->param.data[j].rindex == rindex)
  1370. {
  1371. parameterId = j;
  1372. break;
  1373. }
  1374. }
  1375. break;
  1376. }
  1377. if (parameterId == UINT32_MAX)
  1378. break;
  1379. std::vector<uint8_t> chunk(carla_getChunkFromBase64String(value));
  1380. CARLA_SAFE_ASSERT_RETURN(chunk.size() > 0,);
  1381. #ifdef CARLA_PROPER_CPP11_SUPPORT
  1382. const uint8_t* const valueptr = chunk.data();
  1383. #else
  1384. const uint8_t* const valueptr = &chunk.front();
  1385. #endif
  1386. float rvalue;
  1387. switch (rdfParam.Type)
  1388. {
  1389. case LV2_PARAMETER_TYPE_BOOL:
  1390. rvalue = *(const int32_t*)valueptr != 0 ? 1.0f : 0.0f;
  1391. break;
  1392. case LV2_PARAMETER_TYPE_INT:
  1393. rvalue = static_cast<float>(*(const int32_t*)valueptr);
  1394. break;
  1395. case LV2_PARAMETER_TYPE_FLOAT:
  1396. rvalue = *(const float*)valueptr;
  1397. break;
  1398. case LV2_PARAMETER_TYPE_DOUBLE:
  1399. rvalue = static_cast<float>(*(const double*)valueptr);
  1400. break;
  1401. default:
  1402. // making compilers happy
  1403. rvalue = pData->param.ranges[parameterId].def;
  1404. break;
  1405. }
  1406. fParamBuffers[parameterId] = pData->param.getFixedValue(parameterId, rvalue);
  1407. break;
  1408. }
  1409. }
  1410. CarlaPlugin::setCustomData(type, key, value, sendGui);
  1411. }
  1412. void setProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool doingInit) noexcept override
  1413. {
  1414. CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
  1415. CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),);
  1416. CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,);
  1417. if (index >= 0 && index < static_cast<int32_t>(fRdfDescriptor->PresetCount))
  1418. {
  1419. const LV2_URID_Map* const uridMap = (const LV2_URID_Map*)fFeatures[kFeatureIdUridMap]->data;
  1420. LilvState* const state = Lv2WorldClass::getInstance().getStateFromURI(fRdfDescriptor->Presets[index].URI,
  1421. uridMap);
  1422. CARLA_SAFE_ASSERT_RETURN(state != nullptr,);
  1423. // invalidate midi-program selection
  1424. CarlaPlugin::setMidiProgram(-1, false, false, sendCallback, false);
  1425. if (fExt.state != nullptr)
  1426. {
  1427. const bool block = (sendGui || sendOsc || sendCallback) && !fHasThreadSafeRestore;
  1428. const ScopedSingleProcessLocker spl(this, block);
  1429. lilv_state_restore(state, fExt.state, fHandle, carla_lilv_set_port_value, this, 0, fFeatures);
  1430. if (fHandle2 != nullptr)
  1431. lilv_state_restore(state, fExt.state, fHandle2, carla_lilv_set_port_value, this, 0, fFeatures);
  1432. }
  1433. else
  1434. {
  1435. lilv_state_emit_port_values(state, carla_lilv_set_port_value, this);
  1436. }
  1437. lilv_state_free(state);
  1438. }
  1439. CarlaPlugin::setProgram(index, sendGui, sendOsc, sendCallback, doingInit);
  1440. }
  1441. void setMidiProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool doingInit) noexcept override
  1442. {
  1443. CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
  1444. CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),);
  1445. CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback || doingInit,);
  1446. if (index >= 0 && fExt.programs != nullptr && fExt.programs->select_program != nullptr)
  1447. {
  1448. const uint32_t bank(pData->midiprog.data[index].bank);
  1449. const uint32_t program(pData->midiprog.data[index].program);
  1450. const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback));
  1451. try {
  1452. fExt.programs->select_program(fHandle, bank, program);
  1453. } CARLA_SAFE_EXCEPTION("select program");
  1454. if (fHandle2 != nullptr)
  1455. {
  1456. try {
  1457. fExt.programs->select_program(fHandle2, bank, program);
  1458. } CARLA_SAFE_EXCEPTION("select program 2");
  1459. }
  1460. }
  1461. CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback, doingInit);
  1462. }
  1463. void setMidiProgramRT(const uint32_t uindex, const bool sendCallbackLater) noexcept override
  1464. {
  1465. CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
  1466. CARLA_SAFE_ASSERT_RETURN(uindex < pData->midiprog.count,);
  1467. if (fExt.programs != nullptr && fExt.programs->select_program != nullptr)
  1468. {
  1469. const uint32_t bank(pData->midiprog.data[uindex].bank);
  1470. const uint32_t program(pData->midiprog.data[uindex].program);
  1471. try {
  1472. fExt.programs->select_program(fHandle, bank, program);
  1473. } CARLA_SAFE_EXCEPTION("select program RT");
  1474. if (fHandle2 != nullptr)
  1475. {
  1476. try {
  1477. fExt.programs->select_program(fHandle2, bank, program);
  1478. } CARLA_SAFE_EXCEPTION("select program RT 2");
  1479. }
  1480. }
  1481. CarlaPlugin::setMidiProgramRT(uindex, sendCallbackLater);
  1482. }
  1483. // -------------------------------------------------------------------
  1484. // Set ui stuff
  1485. void setCustomUITitle(const char* const title) noexcept override
  1486. {
  1487. setWindowTitle(title);
  1488. CarlaPlugin::setCustomUITitle(title);
  1489. }
  1490. void showCustomUI(const bool yesNo) override
  1491. {
  1492. if (fUI.type == UI::TYPE_NULL)
  1493. {
  1494. if (yesNo && fFilePathURI.isNotEmpty())
  1495. {
  1496. const char* const path = pData->engine->runFileCallback(FILE_CALLBACK_OPEN, false, "Open File", "");
  1497. if (path != nullptr && path[0] != '\0')
  1498. {
  1499. carla_stdout("LV2 file path to send: '%s'", path);
  1500. writeAtomPath(path, getCustomURID(fFilePathURI));
  1501. }
  1502. }
  1503. else
  1504. {
  1505. CARLA_SAFE_ASSERT(!yesNo);
  1506. }
  1507. pData->engine->callback(true, true,
  1508. ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0, 0.0f, nullptr);
  1509. return;
  1510. }
  1511. const uintptr_t frontendWinId = pData->engine->getOptions().frontendWinId;
  1512. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1513. if (! yesNo)
  1514. pData->transientTryCounter = 0;
  1515. #endif
  1516. #ifndef LV2_UIS_ONLY_INPROCESS
  1517. if (fUI.type == UI::TYPE_BRIDGE)
  1518. {
  1519. if (yesNo)
  1520. {
  1521. if (fPipeServer.isPipeRunning())
  1522. {
  1523. fPipeServer.writeFocusMessage();
  1524. return;
  1525. }
  1526. if (! fPipeServer.startPipeServer(std::min(fLv2Options.sequenceSize, 819200)))
  1527. {
  1528. pData->engine->callback(true, true,
  1529. ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0, 0.0f, nullptr);
  1530. return;
  1531. }
  1532. // manually write messages so we can take the lock for ourselves
  1533. {
  1534. char tmpBuf[0xff];
  1535. tmpBuf[0xfe] = '\0';
  1536. const CarlaMutexLocker cml(fPipeServer.getPipeLock());
  1537. const CarlaScopedLocale csl;
  1538. // write URI mappings
  1539. uint32_t u = 0;
  1540. for (std::vector<std::string>::iterator it=fCustomURIDs.begin(), end=fCustomURIDs.end(); it != end; ++it, ++u)
  1541. {
  1542. if (u < kUridCount)
  1543. continue;
  1544. const std::string& uri(*it);
  1545. if (! fPipeServer.writeMessage("urid\n", 5))
  1546. return;
  1547. std::snprintf(tmpBuf, 0xfe, "%u\n", u);
  1548. if (! fPipeServer.writeMessage(tmpBuf))
  1549. return;
  1550. std::snprintf(tmpBuf, 0xfe, "%lu\n", static_cast<long unsigned>(uri.length()));
  1551. if (! fPipeServer.writeMessage(tmpBuf))
  1552. return;
  1553. if (! fPipeServer.writeAndFixMessage(uri.c_str()))
  1554. return;
  1555. }
  1556. // write UI options
  1557. if (! fPipeServer.writeMessage("uiOptions\n", 10))
  1558. return;
  1559. const EngineOptions& opts(pData->engine->getOptions());
  1560. std::snprintf(tmpBuf, 0xff, "%g\n", pData->engine->getSampleRate());
  1561. if (! fPipeServer.writeMessage(tmpBuf))
  1562. return;
  1563. std::snprintf(tmpBuf, 0xff, "%u\n", opts.bgColor);
  1564. if (! fPipeServer.writeMessage(tmpBuf))
  1565. return;
  1566. std::snprintf(tmpBuf, 0xff, "%u\n", opts.fgColor);
  1567. if (! fPipeServer.writeMessage(tmpBuf))
  1568. return;
  1569. std::snprintf(tmpBuf, 0xff, "%.12g\n", static_cast<double>(opts.uiScale));
  1570. if (! fPipeServer.writeMessage(tmpBuf))
  1571. return;
  1572. std::snprintf(tmpBuf, 0xff, "%s\n", bool2str(true)); // useTheme
  1573. if (! fPipeServer.writeMessage(tmpBuf))
  1574. return;
  1575. std::snprintf(tmpBuf, 0xff, "%s\n", bool2str(true)); // useThemeColors
  1576. if (! fPipeServer.writeMessage(tmpBuf))
  1577. return;
  1578. if (! fPipeServer.writeAndFixMessage(fLv2Options.windowTitle != nullptr
  1579. ? fLv2Options.windowTitle
  1580. : ""))
  1581. return;
  1582. std::snprintf(tmpBuf, 0xff, P_INTPTR "\n", frontendWinId);
  1583. if (! fPipeServer.writeMessage(tmpBuf))
  1584. return;
  1585. // write parameter values
  1586. for (uint32_t i=0; i < pData->param.count; ++i)
  1587. {
  1588. ParameterData& pdata(pData->param.data[i]);
  1589. if (pdata.hints & PARAMETER_IS_NOT_SAVED)
  1590. {
  1591. int32_t rindex = pdata.rindex;
  1592. CARLA_SAFE_ASSERT_CONTINUE(rindex - static_cast<int32_t>(fRdfDescriptor->PortCount) >= 0);
  1593. rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount);
  1594. CARLA_SAFE_ASSERT_CONTINUE(rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount));
  1595. if (! fPipeServer.writeLv2ParameterMessage(fRdfDescriptor->Parameters[rindex].URI,
  1596. getParameterValue(i), false))
  1597. return;
  1598. }
  1599. else
  1600. {
  1601. if (! fPipeServer.writeControlMessage(static_cast<uint32_t>(pData->param.data[i].rindex),
  1602. getParameterValue(i), false))
  1603. return;
  1604. }
  1605. }
  1606. // ready to show
  1607. if (! fPipeServer.writeMessage("show\n", 5))
  1608. return;
  1609. fPipeServer.flushMessages();
  1610. }
  1611. #ifndef BUILD_BRIDGE
  1612. if (fUI.rdfDescriptor->Type == LV2_UI_MOD)
  1613. pData->tryTransient();
  1614. #endif
  1615. }
  1616. else
  1617. {
  1618. fPipeServer.stopPipeServer(pData->engine->getOptions().uiBridgesTimeout);
  1619. }
  1620. return;
  1621. }
  1622. #endif
  1623. // take some precautions
  1624. CARLA_SAFE_ASSERT_RETURN(fUI.descriptor != nullptr,);
  1625. CARLA_SAFE_ASSERT_RETURN(fUI.rdfDescriptor != nullptr,);
  1626. if (yesNo)
  1627. {
  1628. CARLA_SAFE_ASSERT_RETURN(fUI.descriptor->instantiate != nullptr,);
  1629. CARLA_SAFE_ASSERT_RETURN(fUI.descriptor->cleanup != nullptr,);
  1630. }
  1631. else
  1632. {
  1633. if (fUI.handle == nullptr)
  1634. return;
  1635. }
  1636. if (yesNo)
  1637. {
  1638. if (fUI.handle == nullptr)
  1639. {
  1640. #ifndef LV2_UIS_ONLY_BRIDGES
  1641. if (fUI.type == UI::TYPE_EMBED && fUI.rdfDescriptor->Type != LV2_UI_NONE && fUI.window == nullptr)
  1642. {
  1643. const char* msg = nullptr;
  1644. const bool isStandalone = pData->engine->getOptions().pluginsAreStandalone;
  1645. switch (fUI.rdfDescriptor->Type)
  1646. {
  1647. case LV2_UI_GTK2:
  1648. case LV2_UI_GTK3:
  1649. case LV2_UI_QT4:
  1650. case LV2_UI_QT5:
  1651. case LV2_UI_EXTERNAL:
  1652. case LV2_UI_OLD_EXTERNAL:
  1653. msg = "Invalid UI type";
  1654. break;
  1655. case LV2_UI_COCOA:
  1656. # ifdef CARLA_OS_MAC
  1657. fUI.window = CarlaPluginUI::newCocoa(this, frontendWinId, isStandalone, isUiResizable());
  1658. # else
  1659. msg = "UI is for MacOS only";
  1660. # endif
  1661. break;
  1662. case LV2_UI_WINDOWS:
  1663. # ifdef CARLA_OS_WIN
  1664. fUI.window = CarlaPluginUI::newWindows(this, frontendWinId, isStandalone, isUiResizable());
  1665. # else
  1666. msg = "UI is for Windows only";
  1667. # endif
  1668. break;
  1669. case LV2_UI_X11:
  1670. # ifdef HAVE_X11
  1671. fUI.window = CarlaPluginUI::newX11(this, frontendWinId, isStandalone, isUiResizable(), true);
  1672. # else
  1673. msg = "UI is only for systems with X11";
  1674. # endif
  1675. break;
  1676. default:
  1677. msg = "Unknown UI type";
  1678. break;
  1679. }
  1680. if (fUI.window == nullptr && fExt.uishow == nullptr)
  1681. return pData->engine->callback(true, true,
  1682. ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, -1, 0, 0, 0.0f, msg);
  1683. if (fUI.window != nullptr)
  1684. fFeatures[kFeatureIdUiParent]->data = fUI.window->getPtr();
  1685. }
  1686. #endif
  1687. fUI.widget = nullptr;
  1688. fUI.handle = fUI.descriptor->instantiate(fUI.descriptor, fRdfDescriptor->URI, fUI.rdfDescriptor->Bundle,
  1689. carla_lv2_ui_write_function, this, &fUI.widget, fFeatures);
  1690. if (fUI.window != nullptr)
  1691. {
  1692. if (fUI.widget != nullptr)
  1693. fUI.window->setChildWindow(fUI.widget);
  1694. fUI.window->setTitle(fLv2Options.windowTitle);
  1695. }
  1696. }
  1697. CARLA_SAFE_ASSERT(fUI.handle != nullptr);
  1698. CARLA_SAFE_ASSERT(fUI.type != UI::TYPE_EXTERNAL || fUI.widget != nullptr);
  1699. if (fUI.handle == nullptr || (fUI.type == UI::TYPE_EXTERNAL && fUI.widget == nullptr))
  1700. {
  1701. fUI.widget = nullptr;
  1702. if (fUI.handle != nullptr)
  1703. {
  1704. fUI.descriptor->cleanup(fUI.handle);
  1705. fUI.handle = nullptr;
  1706. }
  1707. return pData->engine->callback(true, true,
  1708. ENGINE_CALLBACK_UI_STATE_CHANGED,
  1709. pData->id,
  1710. -1,
  1711. 0, 0, 0.0f,
  1712. "Plugin refused to open its own UI");
  1713. }
  1714. updateUi();
  1715. #ifndef LV2_UIS_ONLY_BRIDGES
  1716. if (fUI.type == UI::TYPE_EMBED)
  1717. {
  1718. if (fUI.window != nullptr)
  1719. {
  1720. fUI.window->show();
  1721. }
  1722. else if (fExt.uishow != nullptr)
  1723. {
  1724. fExt.uishow->show(fUI.handle);
  1725. # ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1726. pData->tryTransient();
  1727. # endif
  1728. }
  1729. }
  1730. else
  1731. #endif
  1732. {
  1733. LV2_EXTERNAL_UI_SHOW((LV2_External_UI_Widget*)fUI.widget);
  1734. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1735. pData->tryTransient();
  1736. #endif
  1737. }
  1738. }
  1739. else
  1740. {
  1741. #ifndef LV2_UIS_ONLY_BRIDGES
  1742. if (fUI.type == UI::TYPE_EMBED)
  1743. {
  1744. if (fUI.window != nullptr)
  1745. fUI.window->hide();
  1746. else if (fExt.uishow != nullptr)
  1747. fExt.uishow->hide(fUI.handle);
  1748. }
  1749. else
  1750. #endif
  1751. {
  1752. CARLA_SAFE_ASSERT(fUI.widget != nullptr);
  1753. if (fUI.widget != nullptr)
  1754. LV2_EXTERNAL_UI_HIDE((LV2_External_UI_Widget*)fUI.widget);
  1755. }
  1756. fUI.descriptor->cleanup(fUI.handle);
  1757. fUI.handle = nullptr;
  1758. fUI.widget = nullptr;
  1759. if (fUI.type == UI::TYPE_EMBED && fUI.window != nullptr)
  1760. {
  1761. delete fUI.window;
  1762. fUI.window = nullptr;
  1763. }
  1764. }
  1765. }
  1766. #ifndef LV2_UIS_ONLY_BRIDGES
  1767. void* embedCustomUI(void* const ptr) override
  1768. {
  1769. CARLA_SAFE_ASSERT_RETURN(fUI.type == UI::TYPE_EMBED, nullptr);
  1770. CARLA_SAFE_ASSERT_RETURN(fUI.descriptor != nullptr, nullptr);
  1771. CARLA_SAFE_ASSERT_RETURN(fUI.descriptor->instantiate != nullptr, nullptr);
  1772. CARLA_SAFE_ASSERT_RETURN(fUI.descriptor->cleanup != nullptr, nullptr);
  1773. CARLA_SAFE_ASSERT_RETURN(fUI.rdfDescriptor->Type != LV2_UI_NONE, nullptr);
  1774. CARLA_SAFE_ASSERT_RETURN(fUI.window == nullptr, nullptr);
  1775. fFeatures[kFeatureIdUiParent]->data = ptr;
  1776. fUI.embedded = true;
  1777. fUI.widget = nullptr;
  1778. fUI.handle = fUI.descriptor->instantiate(fUI.descriptor, fRdfDescriptor->URI, fUI.rdfDescriptor->Bundle,
  1779. carla_lv2_ui_write_function, this, &fUI.widget, fFeatures);
  1780. updateUi();
  1781. return fUI.widget;
  1782. }
  1783. #endif
  1784. void idle() override
  1785. {
  1786. if (fAtomBufferWorkerIn.isDataAvailableForReading())
  1787. {
  1788. Lv2AtomRingBuffer tmpRingBuffer(fAtomBufferWorkerIn, fAtomBufferWorkerInTmpData);
  1789. CARLA_SAFE_ASSERT_RETURN(tmpRingBuffer.isDataAvailableForReading(),);
  1790. CARLA_SAFE_ASSERT_RETURN(fExt.worker != nullptr && fExt.worker->work != nullptr,);
  1791. const size_t localSize = fAtomBufferWorkerIn.getSize();
  1792. uint8_t* const localData = new uint8_t[localSize];
  1793. LV2_Atom* const localAtom = static_cast<LV2_Atom*>(static_cast<void*>(localData));
  1794. localAtom->size = localSize;
  1795. uint32_t portIndex;
  1796. for (; tmpRingBuffer.get(portIndex, localAtom); localAtom->size = localSize)
  1797. {
  1798. CARLA_SAFE_ASSERT_CONTINUE(localAtom->type == kUridCarlaAtomWorkerIn);
  1799. fExt.worker->work(fHandle, carla_lv2_worker_respond, this, localAtom->size, LV2_ATOM_BODY_CONST(localAtom));
  1800. }
  1801. delete[] localData;
  1802. }
  1803. if (fInlineDisplayNeedsRedraw)
  1804. {
  1805. // TESTING
  1806. CARLA_SAFE_ASSERT(pData->enabled)
  1807. CARLA_SAFE_ASSERT(!pData->engine->isAboutToClose());
  1808. CARLA_SAFE_ASSERT(pData->client->isActive());
  1809. if (pData->enabled && !pData->engine->isAboutToClose() && pData->client->isActive())
  1810. {
  1811. const int64_t timeNow = water::Time::currentTimeMillis();
  1812. if (timeNow - fInlineDisplayLastRedrawTime > (1000 / 30))
  1813. {
  1814. fInlineDisplayNeedsRedraw = false;
  1815. fInlineDisplayLastRedrawTime = timeNow;
  1816. pData->engine->callback(true, true,
  1817. ENGINE_CALLBACK_INLINE_DISPLAY_REDRAW,
  1818. pData->id,
  1819. 0, 0, 0, 0.0f, nullptr);
  1820. }
  1821. }
  1822. else
  1823. {
  1824. fInlineDisplayNeedsRedraw = false;
  1825. }
  1826. }
  1827. CarlaPlugin::idle();
  1828. }
  1829. void uiIdle() override
  1830. {
  1831. if (const char* const fileNeededForURI = fUI.fileNeededForURI)
  1832. {
  1833. fUI.fileBrowserOpen = true;
  1834. fUI.fileNeededForURI = nullptr;
  1835. const char* const path = pData->engine->runFileCallback(FILE_CALLBACK_OPEN,
  1836. /* isDir */ false,
  1837. /* title */ "File open",
  1838. /* filters */ "");
  1839. fUI.fileBrowserOpen = false;
  1840. if (path != nullptr)
  1841. {
  1842. carla_stdout("LV2 requested path to send: '%s'", path);
  1843. writeAtomPath(path, getCustomURID(fileNeededForURI));
  1844. }
  1845. // this function will be called recursively, stop here
  1846. return;
  1847. }
  1848. if (fAtomBufferUiOut.isDataAvailableForReading())
  1849. {
  1850. Lv2AtomRingBuffer tmpRingBuffer(fAtomBufferUiOut, fAtomBufferUiOutTmpData);
  1851. CARLA_SAFE_ASSERT(tmpRingBuffer.isDataAvailableForReading());
  1852. const size_t localSize = fAtomBufferUiOut.getSize();
  1853. uint8_t* const localData = new uint8_t[localSize];
  1854. LV2_Atom* const localAtom = static_cast<LV2_Atom*>(static_cast<void*>(localData));
  1855. localAtom->size = localSize;
  1856. uint32_t portIndex;
  1857. const bool hasPortEvent(fUI.handle != nullptr &&
  1858. fUI.descriptor != nullptr &&
  1859. fUI.descriptor->port_event != nullptr);
  1860. for (; tmpRingBuffer.get(portIndex, localAtom); localAtom->size = localSize)
  1861. {
  1862. #ifndef LV2_UIS_ONLY_INPROCESS
  1863. if (fUI.type == UI::TYPE_BRIDGE)
  1864. {
  1865. if (fPipeServer.isPipeRunning())
  1866. fPipeServer.writeLv2AtomMessage(portIndex, localAtom);
  1867. }
  1868. else
  1869. #endif
  1870. {
  1871. if (hasPortEvent && ! fNeedsUiClose)
  1872. fUI.descriptor->port_event(fUI.handle, portIndex, lv2_atom_total_size(localAtom), kUridAtomTransferEvent, localAtom);
  1873. }
  1874. inspectAtomForParameterChange(localAtom);
  1875. }
  1876. delete[] localData;
  1877. }
  1878. #ifndef LV2_UIS_ONLY_INPROCESS
  1879. if (fPipeServer.isPipeRunning())
  1880. {
  1881. fPipeServer.idlePipe();
  1882. switch (fPipeServer.getAndResetUiState())
  1883. {
  1884. case CarlaPipeServerLV2::UiNone:
  1885. case CarlaPipeServerLV2::UiShow:
  1886. break;
  1887. case CarlaPipeServerLV2::UiHide:
  1888. fPipeServer.stopPipeServer(2000);
  1889. // fall through
  1890. case CarlaPipeServerLV2::UiCrashed:
  1891. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1892. pData->transientTryCounter = 0;
  1893. #endif
  1894. pData->engine->callback(true, true,
  1895. ENGINE_CALLBACK_UI_STATE_CHANGED,
  1896. pData->id,
  1897. 0,
  1898. 0, 0, 0.0f, nullptr);
  1899. break;
  1900. }
  1901. }
  1902. else
  1903. {
  1904. // TODO - detect if ui-bridge crashed
  1905. }
  1906. #endif
  1907. if (fNeedsUiClose)
  1908. {
  1909. fNeedsUiClose = false;
  1910. showCustomUI(false);
  1911. pData->engine->callback(true, true,
  1912. ENGINE_CALLBACK_UI_STATE_CHANGED,
  1913. pData->id,
  1914. 0,
  1915. 0, 0, 0.0f, nullptr);
  1916. }
  1917. else if (fUI.handle != nullptr && fUI.descriptor != nullptr)
  1918. {
  1919. if (fUI.type == UI::TYPE_EXTERNAL && fUI.widget != nullptr)
  1920. LV2_EXTERNAL_UI_RUN((LV2_External_UI_Widget*)fUI.widget);
  1921. #ifndef LV2_UIS_ONLY_BRIDGES
  1922. else if (fUI.type == UI::TYPE_EMBED && fUI.window != nullptr)
  1923. fUI.window->idle();
  1924. // note: UI might have been closed by window idle
  1925. if (fNeedsUiClose)
  1926. {
  1927. pass();
  1928. }
  1929. else if (fUI.handle != nullptr && fExt.uiidle != nullptr && fExt.uiidle->idle(fUI.handle) != 0)
  1930. {
  1931. showCustomUI(false);
  1932. pData->engine->callback(true, true,
  1933. ENGINE_CALLBACK_UI_STATE_CHANGED,
  1934. pData->id,
  1935. 0,
  1936. 0, 0, 0.0f, nullptr);
  1937. CARLA_SAFE_ASSERT(fUI.handle == nullptr);
  1938. }
  1939. #endif
  1940. }
  1941. CarlaPlugin::uiIdle();
  1942. }
  1943. // -------------------------------------------------------------------
  1944. // Plugin state
  1945. void reload() override
  1946. {
  1947. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr,);
  1948. CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
  1949. CARLA_SAFE_ASSERT_RETURN(fDescriptor != nullptr,);
  1950. CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr,);
  1951. carla_debug("CarlaPluginLV2::reload() - start");
  1952. const EngineProcessMode processMode(pData->engine->getProccessMode());
  1953. // Safely disable plugin for reload
  1954. const ScopedDisabler sd(this);
  1955. if (pData->active)
  1956. deactivate();
  1957. clearBuffers();
  1958. const float sampleRate(static_cast<float>(pData->engine->getSampleRate()));
  1959. const uint32_t portCount(fRdfDescriptor->PortCount);
  1960. uint32_t aIns, aOuts, cvIns, cvOuts, params;
  1961. aIns = aOuts = cvIns = cvOuts = params = 0;
  1962. LinkedList<uint> evIns, evOuts;
  1963. const uint32_t eventBufferSize = static_cast<uint32_t>(fLv2Options.sequenceSize) + 0xff;
  1964. bool forcedStereoIn, forcedStereoOut;
  1965. forcedStereoIn = forcedStereoOut = false;
  1966. bool needsCtrlIn, needsCtrlOut, hasPatchParameterOutputs;
  1967. needsCtrlIn = needsCtrlOut = hasPatchParameterOutputs = false;
  1968. for (uint32_t i=0; i < portCount; ++i)
  1969. {
  1970. const LV2_Property portTypes = fRdfDescriptor->Ports[i].Types;
  1971. if (LV2_IS_PORT_AUDIO(portTypes))
  1972. {
  1973. if (LV2_IS_PORT_INPUT(portTypes))
  1974. aIns += 1;
  1975. else if (LV2_IS_PORT_OUTPUT(portTypes))
  1976. aOuts += 1;
  1977. }
  1978. else if (LV2_IS_PORT_CV(portTypes))
  1979. {
  1980. if (LV2_IS_PORT_INPUT(portTypes))
  1981. cvIns += 1;
  1982. else if (LV2_IS_PORT_OUTPUT(portTypes))
  1983. cvOuts += 1;
  1984. }
  1985. else if (LV2_IS_PORT_ATOM_SEQUENCE(portTypes))
  1986. {
  1987. if (LV2_IS_PORT_INPUT(portTypes))
  1988. evIns.append(CARLA_EVENT_DATA_ATOM);
  1989. else if (LV2_IS_PORT_OUTPUT(portTypes))
  1990. evOuts.append(CARLA_EVENT_DATA_ATOM);
  1991. }
  1992. else if (LV2_IS_PORT_EVENT(portTypes))
  1993. {
  1994. if (LV2_IS_PORT_INPUT(portTypes))
  1995. evIns.append(CARLA_EVENT_DATA_EVENT);
  1996. else if (LV2_IS_PORT_OUTPUT(portTypes))
  1997. evOuts.append(CARLA_EVENT_DATA_EVENT);
  1998. }
  1999. else if (LV2_IS_PORT_MIDI_LL(portTypes))
  2000. {
  2001. if (LV2_IS_PORT_INPUT(portTypes))
  2002. evIns.append(CARLA_EVENT_DATA_MIDI_LL);
  2003. else if (LV2_IS_PORT_OUTPUT(portTypes))
  2004. evOuts.append(CARLA_EVENT_DATA_MIDI_LL);
  2005. }
  2006. else if (LV2_IS_PORT_CONTROL(portTypes))
  2007. params += 1;
  2008. }
  2009. for (uint32_t i=0; i < fRdfDescriptor->ParameterCount; ++i)
  2010. {
  2011. switch (fRdfDescriptor->Parameters[i].Type)
  2012. {
  2013. case LV2_PARAMETER_TYPE_BOOL:
  2014. case LV2_PARAMETER_TYPE_INT:
  2015. // case LV2_PARAMETER_TYPE_LONG:
  2016. case LV2_PARAMETER_TYPE_FLOAT:
  2017. case LV2_PARAMETER_TYPE_DOUBLE:
  2018. params += 1;
  2019. break;
  2020. case LV2_PARAMETER_TYPE_PATH:
  2021. if (fFilePathURI.isEmpty())
  2022. fFilePathURI = fRdfDescriptor->Parameters[i].URI;
  2023. break;
  2024. }
  2025. }
  2026. if ((pData->options & PLUGIN_OPTION_FORCE_STEREO) != 0 && aIns <= 1 && aOuts <= 1 && evOuts.count() == 0 && fExt.state == nullptr && fExt.worker == nullptr)
  2027. {
  2028. if (fHandle2 == nullptr)
  2029. {
  2030. try {
  2031. fHandle2 = fDescriptor->instantiate(fDescriptor, sampleRate, fRdfDescriptor->Bundle, fFeatures);
  2032. } catch(...) {}
  2033. }
  2034. if (fHandle2 != nullptr)
  2035. {
  2036. if (aIns == 1)
  2037. {
  2038. aIns = 2;
  2039. forcedStereoIn = true;
  2040. }
  2041. if (aOuts == 1)
  2042. {
  2043. aOuts = 2;
  2044. forcedStereoOut = true;
  2045. }
  2046. }
  2047. }
  2048. if (aIns > 0)
  2049. {
  2050. pData->audioIn.createNew(aIns);
  2051. fAudioInBuffers = new float*[aIns];
  2052. for (uint32_t i=0; i < aIns; ++i)
  2053. fAudioInBuffers[i] = nullptr;
  2054. }
  2055. if (aOuts > 0)
  2056. {
  2057. pData->audioOut.createNew(aOuts);
  2058. fAudioOutBuffers = new float*[aOuts];
  2059. needsCtrlIn = true;
  2060. for (uint32_t i=0; i < aOuts; ++i)
  2061. fAudioOutBuffers[i] = nullptr;
  2062. }
  2063. if (cvIns > 0)
  2064. {
  2065. pData->cvIn.createNew(cvIns);
  2066. fCvInBuffers = new float*[cvIns];
  2067. for (uint32_t i=0; i < cvIns; ++i)
  2068. fCvInBuffers[i] = nullptr;
  2069. }
  2070. if (cvOuts > 0)
  2071. {
  2072. pData->cvOut.createNew(cvOuts);
  2073. fCvOutBuffers = new float*[cvOuts];
  2074. for (uint32_t i=0; i < cvOuts; ++i)
  2075. fCvOutBuffers[i] = nullptr;
  2076. }
  2077. if (params > 0)
  2078. {
  2079. pData->param.createNew(params, true);
  2080. fParamBuffers = new float[params];
  2081. carla_zeroFloats(fParamBuffers, params);
  2082. }
  2083. if (const uint32_t count = static_cast<uint32_t>(evIns.count()))
  2084. {
  2085. fEventsIn.createNew(count);
  2086. for (uint32_t i=0; i < count; ++i)
  2087. {
  2088. const uint32_t& type(evIns.getAt(i, 0x0));
  2089. if (type == CARLA_EVENT_DATA_ATOM)
  2090. {
  2091. fEventsIn.data[i].type = CARLA_EVENT_DATA_ATOM;
  2092. fEventsIn.data[i].atom = lv2_atom_buffer_new(eventBufferSize, kUridNull, kUridAtomSequence, true);
  2093. }
  2094. else if (type == CARLA_EVENT_DATA_EVENT)
  2095. {
  2096. fEventsIn.data[i].type = CARLA_EVENT_DATA_EVENT;
  2097. fEventsIn.data[i].event = lv2_event_buffer_new(eventBufferSize, LV2_EVENT_AUDIO_STAMP);
  2098. }
  2099. else if (type == CARLA_EVENT_DATA_MIDI_LL)
  2100. {
  2101. fEventsIn.data[i].type = CARLA_EVENT_DATA_MIDI_LL;
  2102. fEventsIn.data[i].midi.capacity = eventBufferSize;
  2103. fEventsIn.data[i].midi.data = new uchar[eventBufferSize];
  2104. }
  2105. }
  2106. }
  2107. else
  2108. {
  2109. fEventsIn.createNew(1);
  2110. fEventsIn.ctrl = &fEventsIn.data[0];
  2111. }
  2112. if (const uint32_t count = static_cast<uint32_t>(evOuts.count()))
  2113. {
  2114. fEventsOut.createNew(count);
  2115. for (uint32_t i=0; i < count; ++i)
  2116. {
  2117. const uint32_t& type(evOuts.getAt(i, 0x0));
  2118. if (type == CARLA_EVENT_DATA_ATOM)
  2119. {
  2120. fEventsOut.data[i].type = CARLA_EVENT_DATA_ATOM;
  2121. fEventsOut.data[i].atom = lv2_atom_buffer_new(eventBufferSize, kUridNull, kUridAtomSequence, false);
  2122. }
  2123. else if (type == CARLA_EVENT_DATA_EVENT)
  2124. {
  2125. fEventsOut.data[i].type = CARLA_EVENT_DATA_EVENT;
  2126. fEventsOut.data[i].event = lv2_event_buffer_new(eventBufferSize, LV2_EVENT_AUDIO_STAMP);
  2127. }
  2128. else if (type == CARLA_EVENT_DATA_MIDI_LL)
  2129. {
  2130. fEventsOut.data[i].type = CARLA_EVENT_DATA_MIDI_LL;
  2131. fEventsOut.data[i].midi.capacity = eventBufferSize;
  2132. fEventsOut.data[i].midi.data = new uchar[eventBufferSize];
  2133. }
  2134. }
  2135. }
  2136. const uint portNameSize(pData->engine->getMaxPortNameSize());
  2137. CarlaString portName;
  2138. uint32_t iCtrl = 0;
  2139. for (uint32_t i=0, iAudioIn=0, iAudioOut=0, iCvIn=0, iCvOut=0, iEvIn=0, iEvOut=0; i < portCount; ++i)
  2140. {
  2141. const LV2_Property portTypes(fRdfDescriptor->Ports[i].Types);
  2142. portName.clear();
  2143. if (LV2_IS_PORT_AUDIO(portTypes) || LV2_IS_PORT_CV(portTypes) || LV2_IS_PORT_ATOM_SEQUENCE(portTypes) || LV2_IS_PORT_EVENT(portTypes) || LV2_IS_PORT_MIDI_LL(portTypes))
  2144. {
  2145. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  2146. {
  2147. portName = pData->name;
  2148. portName += ":";
  2149. }
  2150. portName += fRdfDescriptor->Ports[i].Name;
  2151. portName.truncate(portNameSize);
  2152. }
  2153. if (LV2_IS_PORT_AUDIO(portTypes))
  2154. {
  2155. if (LV2_IS_PORT_INPUT(portTypes))
  2156. {
  2157. const uint32_t j = iAudioIn++;
  2158. pData->audioIn.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, true, j);
  2159. pData->audioIn.ports[j].rindex = i;
  2160. if (forcedStereoIn)
  2161. {
  2162. portName += "_2";
  2163. pData->audioIn.ports[1].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, true, 1);
  2164. pData->audioIn.ports[1].rindex = i;
  2165. }
  2166. }
  2167. else if (LV2_IS_PORT_OUTPUT(portTypes))
  2168. {
  2169. const uint32_t j = iAudioOut++;
  2170. pData->audioOut.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false, j);
  2171. pData->audioOut.ports[j].rindex = i;
  2172. if (forcedStereoOut)
  2173. {
  2174. portName += "_2";
  2175. pData->audioOut.ports[1].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false, 1);
  2176. pData->audioOut.ports[1].rindex = i;
  2177. }
  2178. }
  2179. else
  2180. carla_stderr2("WARNING - Got a broken Port (Audio, but not input or output)");
  2181. }
  2182. else if (LV2_IS_PORT_CV(portTypes))
  2183. {
  2184. const LV2_RDF_PortPoints portPoints(fRdfDescriptor->Ports[i].Points);
  2185. float min, max;
  2186. // min value
  2187. if (LV2_HAVE_MINIMUM_PORT_POINT(portPoints.Hints))
  2188. min = portPoints.Minimum;
  2189. else
  2190. min = -1.0f;
  2191. // max value
  2192. if (LV2_HAVE_MAXIMUM_PORT_POINT(portPoints.Hints))
  2193. max = portPoints.Maximum;
  2194. else
  2195. max = 1.0f;
  2196. if (LV2_IS_PORT_INPUT(portTypes))
  2197. {
  2198. const uint32_t j = iCvIn++;
  2199. pData->cvIn.ports[j].port = (CarlaEngineCVPort*)pData->client->addPort(kEnginePortTypeCV, portName, true, j);
  2200. pData->cvIn.ports[j].rindex = i;
  2201. pData->cvIn.ports[j].port->setRange(min, max);
  2202. }
  2203. else if (LV2_IS_PORT_OUTPUT(portTypes))
  2204. {
  2205. const uint32_t j = iCvOut++;
  2206. pData->cvOut.ports[j].port = (CarlaEngineCVPort*)pData->client->addPort(kEnginePortTypeCV, portName, false, j);
  2207. pData->cvOut.ports[j].rindex = i;
  2208. pData->cvOut.ports[j].port->setRange(min, max);
  2209. }
  2210. else
  2211. carla_stderr("WARNING - Got a broken Port (CV, but not input or output)");
  2212. }
  2213. else if (LV2_IS_PORT_ATOM_SEQUENCE(portTypes))
  2214. {
  2215. if (LV2_IS_PORT_INPUT(portTypes))
  2216. {
  2217. const uint32_t j = iEvIn++;
  2218. fDescriptor->connect_port(fHandle, i, &fEventsIn.data[j].atom->atoms);
  2219. if (fHandle2 != nullptr)
  2220. fDescriptor->connect_port(fHandle2, i, &fEventsIn.data[j].atom->atoms);
  2221. fEventsIn.data[j].rindex = i;
  2222. if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
  2223. fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MIDI;
  2224. if (portTypes & LV2_PORT_DATA_PATCH_MESSAGE)
  2225. fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MESSAGE;
  2226. if (portTypes & LV2_PORT_DATA_TIME_POSITION)
  2227. fEventsIn.data[j].type |= CARLA_EVENT_TYPE_TIME;
  2228. if (evIns.count() == 1)
  2229. {
  2230. fEventsIn.ctrl = &fEventsIn.data[j];
  2231. fEventsIn.ctrlIndex = j;
  2232. if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
  2233. needsCtrlIn = true;
  2234. }
  2235. else
  2236. {
  2237. if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
  2238. fEventsIn.data[j].port = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, j);
  2239. if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
  2240. {
  2241. fEventsIn.ctrl = &fEventsIn.data[j];
  2242. fEventsIn.ctrlIndex = j;
  2243. }
  2244. }
  2245. }
  2246. else if (LV2_IS_PORT_OUTPUT(portTypes))
  2247. {
  2248. const uint32_t j = iEvOut++;
  2249. fDescriptor->connect_port(fHandle, i, &fEventsOut.data[j].atom->atoms);
  2250. if (fHandle2 != nullptr)
  2251. fDescriptor->connect_port(fHandle2, i, &fEventsOut.data[j].atom->atoms);
  2252. fEventsOut.data[j].rindex = i;
  2253. if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
  2254. fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MIDI;
  2255. if (portTypes & LV2_PORT_DATA_PATCH_MESSAGE)
  2256. fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MESSAGE;
  2257. if (portTypes & LV2_PORT_DATA_TIME_POSITION)
  2258. fEventsOut.data[j].type |= CARLA_EVENT_TYPE_TIME;
  2259. if (evOuts.count() == 1)
  2260. {
  2261. fEventsOut.ctrl = &fEventsOut.data[j];
  2262. fEventsOut.ctrlIndex = j;
  2263. if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
  2264. needsCtrlOut = true;
  2265. }
  2266. else
  2267. {
  2268. if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
  2269. fEventsOut.data[j].port = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false, j);
  2270. if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
  2271. {
  2272. fEventsOut.ctrl = &fEventsOut.data[j];
  2273. fEventsOut.ctrlIndex = j;
  2274. }
  2275. }
  2276. }
  2277. else
  2278. carla_stderr2("WARNING - Got a broken Port (Atom-Sequence, but not input or output)");
  2279. }
  2280. else if (LV2_IS_PORT_EVENT(portTypes))
  2281. {
  2282. if (LV2_IS_PORT_INPUT(portTypes))
  2283. {
  2284. const uint32_t j = iEvIn++;
  2285. fDescriptor->connect_port(fHandle, i, fEventsIn.data[j].event);
  2286. if (fHandle2 != nullptr)
  2287. fDescriptor->connect_port(fHandle2, i, fEventsIn.data[j].event);
  2288. fEventsIn.data[j].rindex = i;
  2289. if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
  2290. fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MIDI;
  2291. if (portTypes & LV2_PORT_DATA_PATCH_MESSAGE)
  2292. fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MESSAGE;
  2293. if (portTypes & LV2_PORT_DATA_TIME_POSITION)
  2294. fEventsIn.data[j].type |= CARLA_EVENT_TYPE_TIME;
  2295. if (evIns.count() == 1)
  2296. {
  2297. fEventsIn.ctrl = &fEventsIn.data[j];
  2298. fEventsIn.ctrlIndex = j;
  2299. if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
  2300. needsCtrlIn = true;
  2301. }
  2302. else
  2303. {
  2304. if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
  2305. fEventsIn.data[j].port = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, j);
  2306. if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
  2307. {
  2308. fEventsIn.ctrl = &fEventsIn.data[j];
  2309. fEventsIn.ctrlIndex = j;
  2310. }
  2311. }
  2312. }
  2313. else if (LV2_IS_PORT_OUTPUT(portTypes))
  2314. {
  2315. const uint32_t j = iEvOut++;
  2316. fDescriptor->connect_port(fHandle, i, fEventsOut.data[j].event);
  2317. if (fHandle2 != nullptr)
  2318. fDescriptor->connect_port(fHandle2, i, fEventsOut.data[j].event);
  2319. fEventsOut.data[j].rindex = i;
  2320. if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
  2321. fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MIDI;
  2322. if (portTypes & LV2_PORT_DATA_PATCH_MESSAGE)
  2323. fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MESSAGE;
  2324. if (portTypes & LV2_PORT_DATA_TIME_POSITION)
  2325. fEventsOut.data[j].type |= CARLA_EVENT_TYPE_TIME;
  2326. if (evOuts.count() == 1)
  2327. {
  2328. fEventsOut.ctrl = &fEventsOut.data[j];
  2329. fEventsOut.ctrlIndex = j;
  2330. if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
  2331. needsCtrlOut = true;
  2332. }
  2333. else
  2334. {
  2335. if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
  2336. fEventsOut.data[j].port = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false, j);
  2337. if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
  2338. {
  2339. fEventsOut.ctrl = &fEventsOut.data[j];
  2340. fEventsOut.ctrlIndex = j;
  2341. }
  2342. }
  2343. }
  2344. else
  2345. carla_stderr2("WARNING - Got a broken Port (Event, but not input or output)");
  2346. }
  2347. else if (LV2_IS_PORT_MIDI_LL(portTypes))
  2348. {
  2349. if (LV2_IS_PORT_INPUT(portTypes))
  2350. {
  2351. const uint32_t j = iEvIn++;
  2352. fDescriptor->connect_port(fHandle, i, &fEventsIn.data[j].midi);
  2353. if (fHandle2 != nullptr)
  2354. fDescriptor->connect_port(fHandle2, i, &fEventsIn.data[j].midi);
  2355. fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MIDI;
  2356. fEventsIn.data[j].rindex = i;
  2357. if (evIns.count() == 1)
  2358. {
  2359. needsCtrlIn = true;
  2360. fEventsIn.ctrl = &fEventsIn.data[j];
  2361. fEventsIn.ctrlIndex = j;
  2362. }
  2363. else
  2364. {
  2365. fEventsIn.data[j].port = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, j);
  2366. if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
  2367. {
  2368. fEventsIn.ctrl = &fEventsIn.data[j];
  2369. fEventsIn.ctrlIndex = j;
  2370. }
  2371. }
  2372. }
  2373. else if (LV2_IS_PORT_OUTPUT(portTypes))
  2374. {
  2375. const uint32_t j = iEvOut++;
  2376. fDescriptor->connect_port(fHandle, i, &fEventsOut.data[j].midi);
  2377. if (fHandle2 != nullptr)
  2378. fDescriptor->connect_port(fHandle2, i, &fEventsOut.data[j].midi);
  2379. fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MIDI;
  2380. fEventsOut.data[j].rindex = i;
  2381. if (evOuts.count() == 1)
  2382. {
  2383. needsCtrlOut = true;
  2384. fEventsOut.ctrl = &fEventsOut.data[j];
  2385. fEventsOut.ctrlIndex = j;
  2386. }
  2387. else
  2388. {
  2389. fEventsOut.data[j].port = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false, j);
  2390. if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
  2391. {
  2392. fEventsOut.ctrl = &fEventsOut.data[j];
  2393. fEventsOut.ctrlIndex = j;
  2394. }
  2395. }
  2396. }
  2397. else
  2398. carla_stderr2("WARNING - Got a broken Port (MIDI, but not input or output)");
  2399. }
  2400. else if (LV2_IS_PORT_CONTROL(portTypes))
  2401. {
  2402. const LV2_Property portProps(fRdfDescriptor->Ports[i].Properties);
  2403. const LV2_Property portDesignation(fRdfDescriptor->Ports[i].Designation);
  2404. const LV2_RDF_PortPoints portPoints(fRdfDescriptor->Ports[i].Points);
  2405. const uint32_t j = iCtrl++;
  2406. pData->param.data[j].index = static_cast<int32_t>(j);
  2407. pData->param.data[j].rindex = static_cast<int32_t>(i);
  2408. float min, max, def, step, stepSmall, stepLarge;
  2409. // min value
  2410. if (LV2_HAVE_MINIMUM_PORT_POINT(portPoints.Hints))
  2411. min = portPoints.Minimum;
  2412. else
  2413. min = 0.0f;
  2414. // max value
  2415. if (LV2_HAVE_MAXIMUM_PORT_POINT(portPoints.Hints))
  2416. max = portPoints.Maximum;
  2417. else
  2418. max = 1.0f;
  2419. if (LV2_IS_PORT_SAMPLE_RATE(portProps))
  2420. {
  2421. min *= sampleRate;
  2422. max *= sampleRate;
  2423. pData->param.data[j].hints |= PARAMETER_USES_SAMPLERATE;
  2424. }
  2425. // stupid hack for ir.lv2 (broken plugin)
  2426. if (std::strcmp(fRdfDescriptor->URI, "http://factorial.hu/plugins/lv2/ir") == 0 && std::strncmp(fRdfDescriptor->Ports[i].Name, "FileHash", 8) == 0)
  2427. {
  2428. min = 0.0f;
  2429. max = (float)0xffffff;
  2430. }
  2431. if (min >= max)
  2432. {
  2433. carla_stderr2("WARNING - Broken plugin parameter '%s': min >= max", fRdfDescriptor->Ports[i].Name);
  2434. max = min + 0.1f;
  2435. }
  2436. // default value
  2437. if (LV2_HAVE_DEFAULT_PORT_POINT(portPoints.Hints))
  2438. {
  2439. def = portPoints.Default;
  2440. }
  2441. else
  2442. {
  2443. // no default value
  2444. if (min < 0.0f && max > 0.0f)
  2445. def = 0.0f;
  2446. else
  2447. def = min;
  2448. }
  2449. if (def < min)
  2450. def = min;
  2451. else if (def > max)
  2452. def = max;
  2453. if (LV2_IS_PORT_TOGGLED(portProps))
  2454. {
  2455. step = max - min;
  2456. stepSmall = step;
  2457. stepLarge = step;
  2458. pData->param.data[j].hints |= PARAMETER_IS_BOOLEAN;
  2459. }
  2460. else if (LV2_IS_PORT_INTEGER(portProps))
  2461. {
  2462. step = 1.0f;
  2463. stepSmall = 1.0f;
  2464. stepLarge = 10.0f;
  2465. pData->param.data[j].hints |= PARAMETER_IS_INTEGER;
  2466. }
  2467. else
  2468. {
  2469. float range = max - min;
  2470. step = range/100.0f;
  2471. stepSmall = range/1000.0f;
  2472. stepLarge = range/10.0f;
  2473. }
  2474. if (LV2_IS_PORT_INPUT(portTypes))
  2475. {
  2476. pData->param.data[j].type = PARAMETER_INPUT;
  2477. if (LV2_IS_PORT_DESIGNATION_LATENCY(portDesignation))
  2478. {
  2479. carla_stderr("Plugin has latency input port, this should not happen!");
  2480. }
  2481. else if (LV2_IS_PORT_DESIGNATION_SAMPLE_RATE(portDesignation))
  2482. {
  2483. def = sampleRate;
  2484. step = 1.0f;
  2485. stepSmall = 1.0f;
  2486. stepLarge = 1.0f;
  2487. pData->param.special[j] = PARAMETER_SPECIAL_SAMPLE_RATE;
  2488. }
  2489. else if (LV2_IS_PORT_DESIGNATION_FREEWHEELING(portDesignation))
  2490. {
  2491. pData->param.special[j] = PARAMETER_SPECIAL_FREEWHEEL;
  2492. }
  2493. else if (LV2_IS_PORT_DESIGNATION_TIME(portDesignation))
  2494. {
  2495. pData->param.special[j] = PARAMETER_SPECIAL_TIME;
  2496. }
  2497. else
  2498. {
  2499. pData->param.data[j].hints |= PARAMETER_IS_ENABLED;
  2500. pData->param.data[j].hints |= PARAMETER_IS_AUTOMATABLE;
  2501. needsCtrlIn = true;
  2502. if (! LV2_IS_PORT_CAUSES_ARTIFACTS(portProps) &&
  2503. ! LV2_IS_PORT_ENUMERATION(portProps) &&
  2504. ! LV2_IS_PORT_EXPENSIVE(portProps) &&
  2505. ! LV2_IS_PORT_NOT_AUTOMATIC(portProps) &&
  2506. ! LV2_IS_PORT_NOT_ON_GUI(portProps) &&
  2507. ! LV2_IS_PORT_TRIGGER(portProps))
  2508. {
  2509. pData->param.data[j].hints |= PARAMETER_CAN_BE_CV_CONTROLLED;
  2510. }
  2511. }
  2512. // MIDI CC value
  2513. const LV2_RDF_PortMidiMap& portMidiMap(fRdfDescriptor->Ports[i].MidiMap);
  2514. if (LV2_IS_PORT_MIDI_MAP_CC(portMidiMap.Type))
  2515. {
  2516. if (portMidiMap.Number < MAX_MIDI_CONTROL && ! MIDI_IS_CONTROL_BANK_SELECT(portMidiMap.Number))
  2517. pData->param.data[j].mappedControlIndex = static_cast<int16_t>(portMidiMap.Number);
  2518. }
  2519. }
  2520. else if (LV2_IS_PORT_OUTPUT(portTypes))
  2521. {
  2522. pData->param.data[j].type = PARAMETER_OUTPUT;
  2523. if (LV2_IS_PORT_DESIGNATION_LATENCY(portDesignation))
  2524. {
  2525. min = 0.0f;
  2526. max = sampleRate;
  2527. def = 0.0f;
  2528. step = 1.0f;
  2529. stepSmall = 1.0f;
  2530. stepLarge = 1.0f;
  2531. pData->param.special[j] = PARAMETER_SPECIAL_LATENCY;
  2532. CARLA_SAFE_ASSERT_INT2(fLatencyIndex == static_cast<int32_t>(j), fLatencyIndex, j);
  2533. }
  2534. else if (LV2_IS_PORT_DESIGNATION_SAMPLE_RATE(portDesignation))
  2535. {
  2536. def = sampleRate;
  2537. step = 1.0f;
  2538. stepSmall = 1.0f;
  2539. stepLarge = 1.0f;
  2540. pData->param.special[j] = PARAMETER_SPECIAL_SAMPLE_RATE;
  2541. }
  2542. else if (LV2_IS_PORT_DESIGNATION_FREEWHEELING(portDesignation))
  2543. {
  2544. carla_stderr("Plugin has freewheeling output port, this should not happen!");
  2545. }
  2546. else if (LV2_IS_PORT_DESIGNATION_TIME(portDesignation))
  2547. {
  2548. pData->param.special[j] = PARAMETER_SPECIAL_TIME;
  2549. }
  2550. else
  2551. {
  2552. pData->param.data[j].hints |= PARAMETER_IS_ENABLED;
  2553. pData->param.data[j].hints |= PARAMETER_IS_AUTOMATABLE;
  2554. needsCtrlOut = true;
  2555. }
  2556. }
  2557. else
  2558. {
  2559. pData->param.data[j].type = PARAMETER_UNKNOWN;
  2560. carla_stderr2("WARNING - Got a broken Port (Control, but not input or output)");
  2561. }
  2562. // extra parameter hints
  2563. if (LV2_IS_PORT_LOGARITHMIC(portProps))
  2564. pData->param.data[j].hints |= PARAMETER_IS_LOGARITHMIC;
  2565. if (LV2_IS_PORT_TRIGGER(portProps))
  2566. pData->param.data[j].hints |= PARAMETER_IS_TRIGGER;
  2567. if (LV2_IS_PORT_STRICT_BOUNDS(portProps))
  2568. pData->param.data[j].hints |= PARAMETER_IS_STRICT_BOUNDS;
  2569. if (LV2_IS_PORT_ENUMERATION(portProps))
  2570. pData->param.data[j].hints |= PARAMETER_USES_SCALEPOINTS;
  2571. // check if parameter is not enabled or automatable
  2572. if (LV2_IS_PORT_NOT_ON_GUI(portProps))
  2573. pData->param.data[j].hints &= ~(PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMATABLE);
  2574. else if (LV2_IS_PORT_CAUSES_ARTIFACTS(portProps) || LV2_IS_PORT_EXPENSIVE(portProps))
  2575. pData->param.data[j].hints &= ~PARAMETER_IS_AUTOMATABLE;
  2576. else if (LV2_IS_PORT_NOT_AUTOMATIC(portProps) || LV2_IS_PORT_NON_AUTOMATABLE(portProps))
  2577. pData->param.data[j].hints &= ~PARAMETER_IS_AUTOMATABLE;
  2578. pData->param.ranges[j].min = min;
  2579. pData->param.ranges[j].max = max;
  2580. pData->param.ranges[j].def = def;
  2581. pData->param.ranges[j].step = step;
  2582. pData->param.ranges[j].stepSmall = stepSmall;
  2583. pData->param.ranges[j].stepLarge = stepLarge;
  2584. // Start parameters in their default values (except freewheel, which is off by default)
  2585. if (pData->param.data[j].type == PARAMETER_INPUT && pData->param.special[j] == PARAMETER_SPECIAL_FREEWHEEL)
  2586. fParamBuffers[j] = min;
  2587. else
  2588. fParamBuffers[j] = def;
  2589. fDescriptor->connect_port(fHandle, i, &fParamBuffers[j]);
  2590. if (fHandle2 != nullptr)
  2591. fDescriptor->connect_port(fHandle2, i, &fParamBuffers[j]);
  2592. }
  2593. else
  2594. {
  2595. // Port Type not supported, but it's optional anyway
  2596. fDescriptor->connect_port(fHandle, i, nullptr);
  2597. if (fHandle2 != nullptr)
  2598. fDescriptor->connect_port(fHandle2, i, nullptr);
  2599. }
  2600. }
  2601. for (uint32_t i=0; i < fRdfDescriptor->ParameterCount; ++i)
  2602. {
  2603. const LV2_RDF_Parameter& rdfParam(fRdfDescriptor->Parameters[i]);
  2604. switch (rdfParam.Type)
  2605. {
  2606. case LV2_PARAMETER_TYPE_BOOL:
  2607. case LV2_PARAMETER_TYPE_INT:
  2608. // case LV2_PARAMETER_TYPE_LONG:
  2609. case LV2_PARAMETER_TYPE_FLOAT:
  2610. case LV2_PARAMETER_TYPE_DOUBLE:
  2611. break;
  2612. default:
  2613. continue;
  2614. }
  2615. const LV2_RDF_PortPoints& portPoints(rdfParam.Points);
  2616. const uint32_t j = iCtrl++;
  2617. pData->param.data[j].index = static_cast<int32_t>(j);
  2618. pData->param.data[j].rindex = static_cast<int32_t>(fRdfDescriptor->PortCount + i);
  2619. float min, max, def, step, stepSmall, stepLarge;
  2620. // min value
  2621. if (LV2_HAVE_MINIMUM_PORT_POINT(portPoints.Hints))
  2622. min = portPoints.Minimum;
  2623. else
  2624. min = 0.0f;
  2625. // max value
  2626. if (LV2_HAVE_MAXIMUM_PORT_POINT(portPoints.Hints))
  2627. max = portPoints.Maximum;
  2628. else
  2629. max = 1.0f;
  2630. if (min >= max)
  2631. {
  2632. carla_stderr2("WARNING - Broken plugin parameter '%s': min >= max", rdfParam.Label);
  2633. max = min + 0.1f;
  2634. }
  2635. // default value
  2636. if (LV2_HAVE_DEFAULT_PORT_POINT(portPoints.Hints))
  2637. {
  2638. def = portPoints.Default;
  2639. }
  2640. else
  2641. {
  2642. // no default value
  2643. if (min < 0.0f && max > 0.0f)
  2644. def = 0.0f;
  2645. else
  2646. def = min;
  2647. }
  2648. if (def < min)
  2649. def = min;
  2650. else if (def > max)
  2651. def = max;
  2652. switch (rdfParam.Type)
  2653. {
  2654. case LV2_PARAMETER_TYPE_BOOL:
  2655. step = max - min;
  2656. stepSmall = step;
  2657. stepLarge = step;
  2658. pData->param.data[j].hints |= PARAMETER_IS_BOOLEAN;
  2659. break;
  2660. case LV2_PARAMETER_TYPE_INT:
  2661. case LV2_PARAMETER_TYPE_LONG:
  2662. step = 1.0f;
  2663. stepSmall = 1.0f;
  2664. stepLarge = 10.0f;
  2665. pData->param.data[j].hints |= PARAMETER_IS_INTEGER;
  2666. break;
  2667. default:
  2668. const float range = max - min;
  2669. step = range/100.0f;
  2670. stepSmall = range/1000.0f;
  2671. stepLarge = range/10.0f;
  2672. break;
  2673. }
  2674. if (rdfParam.Flags & LV2_PARAMETER_FLAG_INPUT)
  2675. {
  2676. pData->param.data[j].type = PARAMETER_INPUT;
  2677. pData->param.data[j].hints |= PARAMETER_IS_ENABLED;
  2678. pData->param.data[j].hints |= PARAMETER_IS_AUTOMATABLE;
  2679. pData->param.data[j].hints |= PARAMETER_IS_NOT_SAVED;
  2680. needsCtrlIn = true;
  2681. if (rdfParam.Flags & LV2_PARAMETER_FLAG_OUTPUT)
  2682. hasPatchParameterOutputs = true;
  2683. if (LV2_IS_PORT_MIDI_MAP_CC(rdfParam.MidiMap.Type))
  2684. {
  2685. if (rdfParam.MidiMap.Number < MAX_MIDI_CONTROL && ! MIDI_IS_CONTROL_BANK_SELECT(rdfParam.MidiMap.Number))
  2686. pData->param.data[j].mappedControlIndex = static_cast<int16_t>(rdfParam.MidiMap.Number);
  2687. }
  2688. }
  2689. else if (rdfParam.Flags & LV2_PARAMETER_FLAG_OUTPUT)
  2690. {
  2691. pData->param.data[j].type = PARAMETER_OUTPUT;
  2692. pData->param.data[j].hints |= PARAMETER_IS_ENABLED;
  2693. pData->param.data[j].hints |= PARAMETER_IS_AUTOMATABLE;
  2694. needsCtrlOut = true;
  2695. hasPatchParameterOutputs = true;
  2696. }
  2697. pData->param.ranges[j].min = min;
  2698. pData->param.ranges[j].max = max;
  2699. pData->param.ranges[j].def = def;
  2700. pData->param.ranges[j].step = step;
  2701. pData->param.ranges[j].stepSmall = stepSmall;
  2702. pData->param.ranges[j].stepLarge = stepLarge;
  2703. fParamBuffers[j] = def;
  2704. }
  2705. if (needsCtrlIn)
  2706. {
  2707. portName.clear();
  2708. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  2709. {
  2710. portName = pData->name;
  2711. portName += ":";
  2712. }
  2713. portName += "events-in";
  2714. portName.truncate(portNameSize);
  2715. pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, 0);
  2716. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  2717. pData->event.cvSourcePorts = pData->client->createCVSourcePorts();
  2718. #endif
  2719. }
  2720. if (needsCtrlOut)
  2721. {
  2722. portName.clear();
  2723. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  2724. {
  2725. portName = pData->name;
  2726. portName += ":";
  2727. }
  2728. portName += "events-out";
  2729. portName.truncate(portNameSize);
  2730. pData->event.portOut = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false, 0);
  2731. }
  2732. if (fExt.worker != nullptr && fEventsIn.ctrl != nullptr)
  2733. {
  2734. fAtomBufferWorkerIn.createBuffer(eventBufferSize);
  2735. fAtomBufferWorkerResp.createBuffer(eventBufferSize);
  2736. fAtomBufferRealtimeSize = fAtomBufferWorkerIn.getSize(); // actual buffer size will be next power of 2
  2737. fAtomBufferRealtime = static_cast<LV2_Atom*>(std::malloc(fAtomBufferRealtimeSize));
  2738. fAtomBufferWorkerInTmpData = new uint8_t[fAtomBufferRealtimeSize];
  2739. }
  2740. if (fRdfDescriptor->ParameterCount > 0 ||
  2741. (fUI.type != UI::TYPE_NULL && fEventsIn.count > 0 && (fEventsIn.data[0].type & CARLA_EVENT_DATA_ATOM) != 0))
  2742. {
  2743. fAtomBufferEvIn.createBuffer(eventBufferSize);
  2744. if (fAtomBufferRealtimeSize == 0)
  2745. {
  2746. fAtomBufferRealtimeSize = fAtomBufferEvIn.getSize(); // actual buffer size will be next power of 2
  2747. fAtomBufferRealtime = static_cast<LV2_Atom*>(std::malloc(fAtomBufferRealtimeSize));
  2748. }
  2749. }
  2750. if (hasPatchParameterOutputs ||
  2751. (fUI.type != UI::TYPE_NULL && fEventsOut.count > 0 && (fEventsOut.data[0].type & CARLA_EVENT_DATA_ATOM) != 0))
  2752. {
  2753. fAtomBufferUiOut.createBuffer(std::min(eventBufferSize*32, 1638400U));
  2754. fAtomBufferUiOutTmpData = new uint8_t[fAtomBufferUiOut.getSize()];
  2755. }
  2756. if (fEventsIn.ctrl != nullptr && fEventsIn.ctrl->port == nullptr)
  2757. fEventsIn.ctrl->port = pData->event.portIn;
  2758. if (fEventsOut.ctrl != nullptr && fEventsOut.ctrl->port == nullptr)
  2759. fEventsOut.ctrl->port = pData->event.portOut;
  2760. if (fEventsIn.ctrl != nullptr && fExt.midnam != nullptr)
  2761. {
  2762. if (char* const midnam = fExt.midnam->midnam(fHandle))
  2763. {
  2764. fEventsIn.ctrl->port->setMetaData("http://www.midi.org/dtds/MIDINameDocument10.dtd",
  2765. midnam, "text/xml");
  2766. if (fExt.midnam->free != nullptr)
  2767. fExt.midnam->free(midnam);
  2768. }
  2769. }
  2770. if (forcedStereoIn || forcedStereoOut)
  2771. pData->options |= PLUGIN_OPTION_FORCE_STEREO;
  2772. else
  2773. pData->options &= ~PLUGIN_OPTION_FORCE_STEREO;
  2774. // plugin hints
  2775. pData->hints = (pData->hints & PLUGIN_HAS_INLINE_DISPLAY) ? PLUGIN_HAS_INLINE_DISPLAY : 0
  2776. | (pData->hints & PLUGIN_NEEDS_UI_MAIN_THREAD) ? PLUGIN_NEEDS_UI_MAIN_THREAD : 0;
  2777. if (isRealtimeSafe())
  2778. pData->hints |= PLUGIN_IS_RTSAFE;
  2779. if (fUI.type != UI::TYPE_NULL || fFilePathURI.isNotEmpty())
  2780. {
  2781. pData->hints |= PLUGIN_HAS_CUSTOM_UI;
  2782. if (fUI.type == UI::TYPE_EMBED)
  2783. {
  2784. switch (fUI.rdfDescriptor->Type)
  2785. {
  2786. case LV2_UI_GTK2:
  2787. case LV2_UI_GTK3:
  2788. case LV2_UI_QT4:
  2789. case LV2_UI_QT5:
  2790. case LV2_UI_EXTERNAL:
  2791. case LV2_UI_OLD_EXTERNAL:
  2792. break;
  2793. default:
  2794. pData->hints |= PLUGIN_HAS_CUSTOM_EMBED_UI;
  2795. break;
  2796. }
  2797. }
  2798. if (fUI.type == UI::TYPE_EMBED || fUI.type == UI::TYPE_EXTERNAL)
  2799. pData->hints |= PLUGIN_NEEDS_UI_MAIN_THREAD;
  2800. else if (fFilePathURI.isNotEmpty())
  2801. pData->hints |= PLUGIN_HAS_CUSTOM_UI_USING_FILE_OPEN;
  2802. }
  2803. if (LV2_IS_GENERATOR(fRdfDescriptor->Type[0], fRdfDescriptor->Type[1]))
  2804. pData->hints |= PLUGIN_IS_SYNTH;
  2805. if (aOuts > 0 && (aIns == aOuts || aIns == 1))
  2806. pData->hints |= PLUGIN_CAN_DRYWET;
  2807. if (aOuts > 0)
  2808. pData->hints |= PLUGIN_CAN_VOLUME;
  2809. if (aOuts >= 2 && aOuts % 2 == 0)
  2810. pData->hints |= PLUGIN_CAN_BALANCE;
  2811. // extra plugin hints
  2812. pData->extraHints = 0x0;
  2813. // check initial latency
  2814. findInitialLatencyValue(aIns, cvIns, aOuts, cvOuts);
  2815. bufferSizeChanged(pData->engine->getBufferSize());
  2816. reloadPrograms(true);
  2817. evIns.clear();
  2818. evOuts.clear();
  2819. if (pData->active)
  2820. activate();
  2821. carla_debug("CarlaPluginLV2::reload() - end");
  2822. }
  2823. void findInitialLatencyValue(const uint32_t aIns,
  2824. const uint32_t cvIns,
  2825. const uint32_t aOuts,
  2826. const uint32_t cvOuts) const
  2827. {
  2828. if (fLatencyIndex < 0)
  2829. return;
  2830. // we need to pre-run the plugin so it can update its latency control-port
  2831. const uint32_t bufferSize = static_cast<uint32_t>(fLv2Options.nominalBufferSize);
  2832. float* tmpIn[96];
  2833. float* tmpOut[96];
  2834. {
  2835. uint32_t i=0;
  2836. for (; i < aIns; ++i)
  2837. {
  2838. tmpIn[i] = new float[bufferSize];
  2839. carla_zeroFloats(tmpIn[i], bufferSize);
  2840. try {
  2841. fDescriptor->connect_port(fHandle, pData->audioIn.ports[i].rindex, tmpIn[i]);
  2842. } CARLA_SAFE_EXCEPTION("LV2 connect_port latency audio input");
  2843. }
  2844. for (uint32_t j=0; j < cvIns; ++i, ++j)
  2845. {
  2846. tmpIn[i] = new float[bufferSize];
  2847. carla_zeroFloats(tmpIn[i], bufferSize);
  2848. try {
  2849. fDescriptor->connect_port(fHandle, pData->cvIn.ports[j].rindex, tmpIn[i]);
  2850. } CARLA_SAFE_EXCEPTION("LV2 connect_port latency cv input");
  2851. }
  2852. }
  2853. {
  2854. uint32_t i=0;
  2855. for (; i < aOuts; ++i)
  2856. {
  2857. tmpOut[i] = new float[bufferSize];
  2858. carla_zeroFloats(tmpOut[i], bufferSize);
  2859. try {
  2860. fDescriptor->connect_port(fHandle, pData->audioOut.ports[i].rindex, tmpOut[i]);
  2861. } CARLA_SAFE_EXCEPTION("LV2 connect_port latency audio output");
  2862. }
  2863. for (uint32_t j=0; j < cvOuts; ++i, ++j)
  2864. {
  2865. tmpOut[i] = new float[bufferSize];
  2866. carla_zeroFloats(tmpOut[i], bufferSize);
  2867. try {
  2868. fDescriptor->connect_port(fHandle, pData->cvOut.ports[j].rindex, tmpOut[i]);
  2869. } CARLA_SAFE_EXCEPTION("LV2 connect_port latency cv output");
  2870. }
  2871. }
  2872. if (fDescriptor->activate != nullptr)
  2873. {
  2874. try {
  2875. fDescriptor->activate(fHandle);
  2876. } CARLA_SAFE_EXCEPTION("LV2 latency activate");
  2877. }
  2878. try {
  2879. fDescriptor->run(fHandle, bufferSize);
  2880. } CARLA_SAFE_EXCEPTION("LV2 latency run");
  2881. if (fDescriptor->deactivate != nullptr)
  2882. {
  2883. try {
  2884. fDescriptor->deactivate(fHandle);
  2885. } CARLA_SAFE_EXCEPTION("LV2 latency deactivate");
  2886. }
  2887. // done, let's get the value
  2888. if (const uint32_t latency = getLatencyInFrames())
  2889. {
  2890. pData->client->setLatency(latency);
  2891. #ifndef BUILD_BRIDGE
  2892. pData->latency.recreateBuffers(std::max(aIns, aOuts), latency);
  2893. #endif
  2894. }
  2895. for (uint32_t i=0; i < aIns + cvIns; ++i)
  2896. delete[] tmpIn[i];
  2897. for (uint32_t i=0; i < aOuts + cvOuts; ++i)
  2898. delete[] tmpOut[i];
  2899. }
  2900. void reloadPrograms(const bool doInit) override
  2901. {
  2902. carla_debug("CarlaPluginLV2::reloadPrograms(%s)", bool2str(doInit));
  2903. const uint32_t oldCount = pData->midiprog.count;
  2904. const int32_t current = pData->midiprog.current;
  2905. // special LV2 programs handling
  2906. if (doInit)
  2907. {
  2908. pData->prog.clear();
  2909. const uint32_t presetCount(fRdfDescriptor->PresetCount);
  2910. if (presetCount > 0)
  2911. {
  2912. pData->prog.createNew(presetCount);
  2913. for (uint32_t i=0; i < presetCount; ++i)
  2914. pData->prog.names[i] = carla_strdup(fRdfDescriptor->Presets[i].Label);
  2915. }
  2916. }
  2917. // Delete old programs
  2918. pData->midiprog.clear();
  2919. // Query new programs
  2920. uint32_t newCount = 0;
  2921. if (fExt.programs != nullptr && fExt.programs->get_program != nullptr && fExt.programs->select_program != nullptr)
  2922. {
  2923. for (; fExt.programs->get_program(fHandle, newCount);)
  2924. ++newCount;
  2925. }
  2926. if (newCount > 0)
  2927. {
  2928. pData->midiprog.createNew(newCount);
  2929. // Update data
  2930. for (uint32_t i=0; i < newCount; ++i)
  2931. {
  2932. const LV2_Program_Descriptor* const pdesc(fExt.programs->get_program(fHandle, i));
  2933. CARLA_SAFE_ASSERT_CONTINUE(pdesc != nullptr);
  2934. CARLA_SAFE_ASSERT(pdesc->name != nullptr);
  2935. pData->midiprog.data[i].bank = pdesc->bank;
  2936. pData->midiprog.data[i].program = pdesc->program;
  2937. pData->midiprog.data[i].name = carla_strdup(pdesc->name);
  2938. }
  2939. }
  2940. if (doInit)
  2941. {
  2942. if (newCount > 0)
  2943. {
  2944. setMidiProgram(0, false, false, false, true);
  2945. }
  2946. else if (fHasLoadDefaultState)
  2947. {
  2948. // load default state
  2949. if (LilvState* const state = Lv2WorldClass::getInstance().getStateFromURI(fDescriptor->URI,
  2950. (const LV2_URID_Map*)fFeatures[kFeatureIdUridMap]->data))
  2951. {
  2952. lilv_state_restore(state, fExt.state, fHandle, carla_lilv_set_port_value, this, 0, fFeatures);
  2953. if (fHandle2 != nullptr)
  2954. lilv_state_restore(state, fExt.state, fHandle2, carla_lilv_set_port_value, this, 0, fFeatures);
  2955. lilv_state_free(state);
  2956. }
  2957. }
  2958. }
  2959. else
  2960. {
  2961. // Check if current program is invalid
  2962. bool programChanged = false;
  2963. if (newCount == oldCount+1)
  2964. {
  2965. // one midi program added, probably created by user
  2966. pData->midiprog.current = static_cast<int32_t>(oldCount);
  2967. programChanged = true;
  2968. }
  2969. else if (current < 0 && newCount > 0)
  2970. {
  2971. // programs exist now, but not before
  2972. pData->midiprog.current = 0;
  2973. programChanged = true;
  2974. }
  2975. else if (current >= 0 && newCount == 0)
  2976. {
  2977. // programs existed before, but not anymore
  2978. pData->midiprog.current = -1;
  2979. programChanged = true;
  2980. }
  2981. else if (current >= static_cast<int32_t>(newCount))
  2982. {
  2983. // current midi program > count
  2984. pData->midiprog.current = 0;
  2985. programChanged = true;
  2986. }
  2987. else
  2988. {
  2989. // no change
  2990. pData->midiprog.current = current;
  2991. }
  2992. if (programChanged)
  2993. setMidiProgram(pData->midiprog.current, true, true, true, false);
  2994. pData->engine->callback(true, true, ENGINE_CALLBACK_RELOAD_PROGRAMS, pData->id, 0, 0, 0, 0.0f, nullptr);
  2995. }
  2996. }
  2997. // -------------------------------------------------------------------
  2998. // Plugin processing
  2999. void activate() noexcept override
  3000. {
  3001. CARLA_SAFE_ASSERT_RETURN(fDescriptor != nullptr,);
  3002. CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
  3003. if (fDescriptor->activate != nullptr)
  3004. {
  3005. try {
  3006. fDescriptor->activate(fHandle);
  3007. } CARLA_SAFE_EXCEPTION("LV2 activate");
  3008. if (fHandle2 != nullptr)
  3009. {
  3010. try {
  3011. fDescriptor->activate(fHandle2);
  3012. } CARLA_SAFE_EXCEPTION("LV2 activate #2");
  3013. }
  3014. }
  3015. fFirstActive = true;
  3016. }
  3017. void deactivate() noexcept override
  3018. {
  3019. CARLA_SAFE_ASSERT_RETURN(fDescriptor != nullptr,);
  3020. CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
  3021. if (fDescriptor->deactivate != nullptr)
  3022. {
  3023. try {
  3024. fDescriptor->deactivate(fHandle);
  3025. } CARLA_SAFE_EXCEPTION("LV2 deactivate");
  3026. if (fHandle2 != nullptr)
  3027. {
  3028. try {
  3029. fDescriptor->deactivate(fHandle2);
  3030. } CARLA_SAFE_EXCEPTION("LV2 deactivate #2");
  3031. }
  3032. }
  3033. }
  3034. void process(const float* const* const audioIn, float** const audioOut,
  3035. const float* const* const cvIn, float** const cvOut, const uint32_t frames) override
  3036. {
  3037. // --------------------------------------------------------------------------------------------------------
  3038. // Check if active
  3039. if (! pData->active)
  3040. {
  3041. // disable any output sound
  3042. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  3043. carla_zeroFloats(audioOut[i], frames);
  3044. for (uint32_t i=0; i < pData->cvOut.count; ++i)
  3045. carla_zeroFloats(cvOut[i], frames);
  3046. return;
  3047. }
  3048. // --------------------------------------------------------------------------------------------------------
  3049. // Event itenerators from different APIs (input)
  3050. for (uint32_t i=0; i < fEventsIn.count; ++i)
  3051. {
  3052. if (fEventsIn.data[i].type & CARLA_EVENT_DATA_ATOM)
  3053. {
  3054. lv2_atom_buffer_reset(fEventsIn.data[i].atom, true);
  3055. lv2_atom_buffer_begin(&fEventsIn.iters[i].atom, fEventsIn.data[i].atom);
  3056. }
  3057. else if (fEventsIn.data[i].type & CARLA_EVENT_DATA_EVENT)
  3058. {
  3059. lv2_event_buffer_reset(fEventsIn.data[i].event, LV2_EVENT_AUDIO_STAMP, fEventsIn.data[i].event->data);
  3060. lv2_event_begin(&fEventsIn.iters[i].event, fEventsIn.data[i].event);
  3061. }
  3062. else if (fEventsIn.data[i].type & CARLA_EVENT_DATA_MIDI_LL)
  3063. {
  3064. fEventsIn.data[i].midi.event_count = 0;
  3065. fEventsIn.data[i].midi.size = 0;
  3066. LV2_MIDIState& midiState(fEventsIn.iters[i].midiState);
  3067. midiState.midi = &fEventsIn.data[i].midi;
  3068. midiState.frame_count = frames;
  3069. midiState.position = 0;
  3070. }
  3071. }
  3072. for (uint32_t i=0; i < fEventsOut.count; ++i)
  3073. {
  3074. if (fEventsOut.data[i].type & CARLA_EVENT_DATA_ATOM)
  3075. {
  3076. lv2_atom_buffer_reset(fEventsOut.data[i].atom, false);
  3077. }
  3078. else if (fEventsOut.data[i].type & CARLA_EVENT_DATA_EVENT)
  3079. {
  3080. lv2_event_buffer_reset(fEventsOut.data[i].event, LV2_EVENT_AUDIO_STAMP, fEventsOut.data[i].event->data);
  3081. }
  3082. else if (fEventsOut.data[i].type & CARLA_EVENT_DATA_MIDI_LL)
  3083. {
  3084. // not needed
  3085. }
  3086. }
  3087. // --------------------------------------------------------------------------------------------------------
  3088. // Check if needs reset
  3089. if (pData->needsReset)
  3090. {
  3091. if (fEventsIn.ctrl != nullptr && (fEventsIn.ctrl->type & CARLA_EVENT_TYPE_MIDI) != 0)
  3092. {
  3093. const uint32_t j = fEventsIn.ctrlIndex;
  3094. CARLA_ASSERT(j < fEventsIn.count);
  3095. uint8_t midiData[3] = { 0, 0, 0 };
  3096. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  3097. {
  3098. for (uint8_t i=0; i < MAX_MIDI_CHANNELS; ++i)
  3099. {
  3100. midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (i & MIDI_CHANNEL_BIT));
  3101. midiData[1] = MIDI_CONTROL_ALL_NOTES_OFF;
  3102. if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
  3103. lv2_atom_buffer_write(&fEventsIn.iters[j].atom, 0, 0, kUridMidiEvent, 3, midiData);
  3104. else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
  3105. lv2_event_write(&fEventsIn.iters[j].event, 0, 0, kUridMidiEvent, 3, midiData);
  3106. else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
  3107. lv2midi_put_event(&fEventsIn.iters[j].midiState, 0.0, 3, midiData);
  3108. midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (i & MIDI_CHANNEL_BIT));
  3109. midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF;
  3110. if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
  3111. lv2_atom_buffer_write(&fEventsIn.iters[j].atom, 0, 0, kUridMidiEvent, 3, midiData);
  3112. else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
  3113. lv2_event_write(&fEventsIn.iters[j].event, 0, 0, kUridMidiEvent, 3, midiData);
  3114. else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
  3115. lv2midi_put_event(&fEventsIn.iters[j].midiState, 0.0, 3, midiData);
  3116. }
  3117. }
  3118. else if (pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS)
  3119. {
  3120. for (uint8_t k=0; k < MAX_MIDI_NOTE; ++k)
  3121. {
  3122. midiData[0] = uint8_t(MIDI_STATUS_NOTE_OFF | (pData->ctrlChannel & MIDI_CHANNEL_BIT));
  3123. midiData[1] = k;
  3124. if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
  3125. lv2_atom_buffer_write(&fEventsIn.iters[j].atom, 0, 0, kUridMidiEvent, 3, midiData);
  3126. else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
  3127. lv2_event_write(&fEventsIn.iters[j].event, 0, 0, kUridMidiEvent, 3, midiData);
  3128. else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
  3129. lv2midi_put_event(&fEventsIn.iters[j].midiState, 0.0, 3, midiData);
  3130. }
  3131. }
  3132. }
  3133. pData->needsReset = false;
  3134. }
  3135. // --------------------------------------------------------------------------------------------------------
  3136. // TimeInfo
  3137. const EngineTimeInfo timeInfo(pData->engine->getTimeInfo());
  3138. if (fFirstActive || fLastTimeInfo != timeInfo)
  3139. {
  3140. bool doPostRt;
  3141. int32_t rindex;
  3142. const double barBeat = static_cast<double>(timeInfo.bbt.beat - 1)
  3143. + (timeInfo.bbt.tick / timeInfo.bbt.ticksPerBeat);
  3144. // update input ports
  3145. for (uint32_t k=0; k < pData->param.count; ++k)
  3146. {
  3147. if (pData->param.data[k].type != PARAMETER_INPUT)
  3148. continue;
  3149. if (pData->param.special[k] != PARAMETER_SPECIAL_TIME)
  3150. continue;
  3151. doPostRt = false;
  3152. rindex = pData->param.data[k].rindex;
  3153. CARLA_SAFE_ASSERT_CONTINUE(rindex >= 0 && rindex < static_cast<int32_t>(fRdfDescriptor->PortCount));
  3154. switch (fRdfDescriptor->Ports[rindex].Designation)
  3155. {
  3156. // Non-BBT
  3157. case LV2_PORT_DESIGNATION_TIME_SPEED:
  3158. if (fLastTimeInfo.playing != timeInfo.playing)
  3159. {
  3160. fParamBuffers[k] = timeInfo.playing ? 1.0f : 0.0f;
  3161. doPostRt = true;
  3162. }
  3163. break;
  3164. case LV2_PORT_DESIGNATION_TIME_FRAME:
  3165. if (fLastTimeInfo.frame != timeInfo.frame)
  3166. {
  3167. fParamBuffers[k] = static_cast<float>(timeInfo.frame);
  3168. doPostRt = true;
  3169. }
  3170. break;
  3171. case LV2_PORT_DESIGNATION_TIME_FRAMES_PER_SECOND:
  3172. break;
  3173. // BBT
  3174. case LV2_PORT_DESIGNATION_TIME_BAR:
  3175. if (timeInfo.bbt.valid && fLastTimeInfo.bbt.bar != timeInfo.bbt.bar)
  3176. {
  3177. fParamBuffers[k] = static_cast<float>(timeInfo.bbt.bar - 1);
  3178. doPostRt = true;
  3179. }
  3180. break;
  3181. case LV2_PORT_DESIGNATION_TIME_BAR_BEAT:
  3182. if (timeInfo.bbt.valid && (carla_isNotEqual(fLastTimeInfo.bbt.tick, timeInfo.bbt.tick) ||
  3183. fLastTimeInfo.bbt.beat != timeInfo.bbt.beat))
  3184. {
  3185. fParamBuffers[k] = static_cast<float>(barBeat);
  3186. doPostRt = true;
  3187. }
  3188. break;
  3189. case LV2_PORT_DESIGNATION_TIME_BEAT:
  3190. if (timeInfo.bbt.valid && fLastTimeInfo.bbt.beat != timeInfo.bbt.beat)
  3191. {
  3192. fParamBuffers[k] = static_cast<float>(timeInfo.bbt.beat - 1);
  3193. doPostRt = true;
  3194. }
  3195. break;
  3196. case LV2_PORT_DESIGNATION_TIME_BEAT_UNIT:
  3197. if (timeInfo.bbt.valid && carla_isNotEqual(fLastTimeInfo.bbt.beatType, timeInfo.bbt.beatType))
  3198. {
  3199. fParamBuffers[k] = timeInfo.bbt.beatType;
  3200. doPostRt = true;
  3201. }
  3202. break;
  3203. case LV2_PORT_DESIGNATION_TIME_BEATS_PER_BAR:
  3204. if (timeInfo.bbt.valid && carla_isNotEqual(fLastTimeInfo.bbt.beatsPerBar, timeInfo.bbt.beatsPerBar))
  3205. {
  3206. fParamBuffers[k] = timeInfo.bbt.beatsPerBar;
  3207. doPostRt = true;
  3208. }
  3209. break;
  3210. case LV2_PORT_DESIGNATION_TIME_BEATS_PER_MINUTE:
  3211. if (timeInfo.bbt.valid && carla_isNotEqual(fLastTimeInfo.bbt.beatsPerMinute, timeInfo.bbt.beatsPerMinute))
  3212. {
  3213. fParamBuffers[k] = static_cast<float>(timeInfo.bbt.beatsPerMinute);
  3214. doPostRt = true;
  3215. }
  3216. break;
  3217. case LV2_PORT_DESIGNATION_TIME_TICKS_PER_BEAT:
  3218. if (timeInfo.bbt.valid && carla_isNotEqual(fLastTimeInfo.bbt.ticksPerBeat, timeInfo.bbt.ticksPerBeat))
  3219. {
  3220. fParamBuffers[k] = static_cast<float>(timeInfo.bbt.ticksPerBeat);
  3221. doPostRt = true;
  3222. }
  3223. break;
  3224. }
  3225. if (doPostRt)
  3226. pData->postponeParameterChangeRtEvent(true, static_cast<int32_t>(k), fParamBuffers[k]);
  3227. }
  3228. for (uint32_t i=0; i < fEventsIn.count; ++i)
  3229. {
  3230. if ((fEventsIn.data[i].type & CARLA_EVENT_DATA_ATOM) == 0 || (fEventsIn.data[i].type & CARLA_EVENT_TYPE_TIME) == 0)
  3231. continue;
  3232. uint8_t timeInfoBuf[256];
  3233. LV2_Atom_Forge atomForge;
  3234. initAtomForge(atomForge);
  3235. lv2_atom_forge_set_buffer(&atomForge, timeInfoBuf, sizeof(timeInfoBuf));
  3236. LV2_Atom_Forge_Frame forgeFrame;
  3237. lv2_atom_forge_object(&atomForge, &forgeFrame, kUridNull, kUridTimePosition);
  3238. lv2_atom_forge_key(&atomForge, kUridTimeSpeed);
  3239. lv2_atom_forge_float(&atomForge, timeInfo.playing ? 1.0f : 0.0f);
  3240. lv2_atom_forge_key(&atomForge, kUridTimeFrame);
  3241. lv2_atom_forge_long(&atomForge, static_cast<int64_t>(timeInfo.frame));
  3242. if (timeInfo.bbt.valid)
  3243. {
  3244. lv2_atom_forge_key(&atomForge, kUridTimeBar);
  3245. lv2_atom_forge_long(&atomForge, timeInfo.bbt.bar - 1);
  3246. lv2_atom_forge_key(&atomForge, kUridTimeBarBeat);
  3247. lv2_atom_forge_float(&atomForge, static_cast<float>(barBeat));
  3248. lv2_atom_forge_key(&atomForge, kUridTimeBeat);
  3249. lv2_atom_forge_double(&atomForge, timeInfo.bbt.beat - 1);
  3250. lv2_atom_forge_key(&atomForge, kUridTimeBeatUnit);
  3251. lv2_atom_forge_int(&atomForge, static_cast<int32_t>(timeInfo.bbt.beatType));
  3252. lv2_atom_forge_key(&atomForge, kUridTimeBeatsPerBar);
  3253. lv2_atom_forge_float(&atomForge, timeInfo.bbt.beatsPerBar);
  3254. lv2_atom_forge_key(&atomForge, kUridTimeBeatsPerMinute);
  3255. lv2_atom_forge_float(&atomForge, static_cast<float>(timeInfo.bbt.beatsPerMinute));
  3256. lv2_atom_forge_key(&atomForge, kUridTimeTicksPerBeat);
  3257. lv2_atom_forge_double(&atomForge, timeInfo.bbt.ticksPerBeat);
  3258. }
  3259. lv2_atom_forge_pop(&atomForge, &forgeFrame);
  3260. LV2_Atom* const atom((LV2_Atom*)timeInfoBuf);
  3261. CARLA_SAFE_ASSERT_BREAK(atom->size < 256);
  3262. // send only deprecated blank object for now
  3263. lv2_atom_buffer_write(&fEventsIn.iters[i].atom, 0, 0, kUridAtomBlank, atom->size, LV2_ATOM_BODY_CONST(atom));
  3264. // for atom:object
  3265. //lv2_atom_buffer_write(&fEventsIn.iters[i].atom, 0, 0, atom->type, atom->size, LV2_ATOM_BODY_CONST(atom));
  3266. }
  3267. pData->postRtEvents.trySplice();
  3268. fLastTimeInfo = timeInfo;
  3269. }
  3270. // --------------------------------------------------------------------------------------------------------
  3271. // Event Input and Processing
  3272. if (fEventsIn.ctrl != nullptr)
  3273. {
  3274. // ----------------------------------------------------------------------------------------------------
  3275. // Message Input
  3276. if (fAtomBufferEvIn.tryLock())
  3277. {
  3278. if (fAtomBufferEvIn.isDataAvailableForReading())
  3279. {
  3280. uint32_t j, portIndex;
  3281. LV2_Atom* const atom = fAtomBufferRealtime;
  3282. atom->size = fAtomBufferRealtimeSize;
  3283. for (; fAtomBufferEvIn.get(portIndex, atom); atom->size = fAtomBufferRealtimeSize)
  3284. {
  3285. j = (portIndex < fEventsIn.count) ? portIndex : fEventsIn.ctrlIndex;
  3286. if (! lv2_atom_buffer_write(&fEventsIn.iters[j].atom, 0, 0, atom->type, atom->size, LV2_ATOM_BODY_CONST(atom)))
  3287. {
  3288. carla_stderr2("Event input buffer full, at least 1 message lost");
  3289. continue;
  3290. }
  3291. inspectAtomForParameterChange(atom);
  3292. }
  3293. }
  3294. fAtomBufferEvIn.unlock();
  3295. }
  3296. // ----------------------------------------------------------------------------------------------------
  3297. // MIDI Input (External)
  3298. if (pData->extNotes.mutex.tryLock())
  3299. {
  3300. if ((fEventsIn.ctrl->type & CARLA_EVENT_TYPE_MIDI) == 0)
  3301. {
  3302. // does not handle MIDI
  3303. pData->extNotes.data.clear();
  3304. }
  3305. else
  3306. {
  3307. const uint32_t j = fEventsIn.ctrlIndex;
  3308. for (RtLinkedList<ExternalMidiNote>::Itenerator it = pData->extNotes.data.begin2(); it.valid(); it.next())
  3309. {
  3310. const ExternalMidiNote& note(it.getValue(kExternalMidiNoteFallback));
  3311. CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);
  3312. uint8_t midiEvent[3];
  3313. midiEvent[0] = uint8_t((note.velo > 0 ? MIDI_STATUS_NOTE_ON : MIDI_STATUS_NOTE_OFF) | (note.channel & MIDI_CHANNEL_BIT));
  3314. midiEvent[1] = note.note;
  3315. midiEvent[2] = note.velo;
  3316. if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
  3317. lv2_atom_buffer_write(&fEventsIn.iters[j].atom, 0, 0, kUridMidiEvent, 3, midiEvent);
  3318. else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
  3319. lv2_event_write(&fEventsIn.iters[j].event, 0, 0, kUridMidiEvent, 3, midiEvent);
  3320. else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
  3321. lv2midi_put_event(&fEventsIn.iters[j].midiState, 0.0, 3, midiEvent);
  3322. }
  3323. pData->extNotes.data.clear();
  3324. }
  3325. pData->extNotes.mutex.unlock();
  3326. } // End of MIDI Input (External)
  3327. // ----------------------------------------------------------------------------------------------------
  3328. // Event Input (System)
  3329. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  3330. bool allNotesOffSent = false;
  3331. #endif
  3332. bool isSampleAccurate = (pData->options & PLUGIN_OPTION_FIXED_BUFFERS) == 0;
  3333. uint32_t startTime = 0;
  3334. uint32_t timeOffset = 0;
  3335. uint32_t nextBankId;
  3336. if (pData->midiprog.current >= 0 && pData->midiprog.count > 0)
  3337. nextBankId = pData->midiprog.data[pData->midiprog.current].bank;
  3338. else
  3339. nextBankId = 0;
  3340. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  3341. if (cvIn != nullptr && pData->event.cvSourcePorts != nullptr)
  3342. pData->event.cvSourcePorts->initPortBuffers(cvIn + pData->cvIn.count, frames, isSampleAccurate, pData->event.portIn);
  3343. #endif
  3344. const uint32_t numEvents = (fEventsIn.ctrl->port != nullptr) ? fEventsIn.ctrl->port->getEventCount() : 0;
  3345. for (uint32_t i=0; i < numEvents; ++i)
  3346. {
  3347. EngineEvent& event(fEventsIn.ctrl->port->getEvent(i));
  3348. uint32_t eventTime = event.time;
  3349. CARLA_SAFE_ASSERT_UINT2_CONTINUE(eventTime < frames, eventTime, frames);
  3350. if (eventTime < timeOffset)
  3351. {
  3352. carla_stderr2("Timing error, eventTime:%u < timeOffset:%u for '%s'",
  3353. eventTime, timeOffset, pData->name);
  3354. eventTime = timeOffset;
  3355. }
  3356. if (isSampleAccurate && eventTime > timeOffset)
  3357. {
  3358. if (processSingle(audioIn, audioOut, cvIn, cvOut, eventTime - timeOffset, timeOffset))
  3359. {
  3360. startTime = 0;
  3361. timeOffset = eventTime;
  3362. if (pData->midiprog.current >= 0 && pData->midiprog.count > 0)
  3363. nextBankId = pData->midiprog.data[pData->midiprog.current].bank;
  3364. else
  3365. nextBankId = 0;
  3366. for (uint32_t j=0; j < fEventsIn.count; ++j)
  3367. {
  3368. if (fEventsIn.data[j].type & CARLA_EVENT_DATA_ATOM)
  3369. {
  3370. lv2_atom_buffer_reset(fEventsIn.data[j].atom, true);
  3371. lv2_atom_buffer_begin(&fEventsIn.iters[j].atom, fEventsIn.data[j].atom);
  3372. }
  3373. else if (fEventsIn.data[j].type & CARLA_EVENT_DATA_EVENT)
  3374. {
  3375. lv2_event_buffer_reset(fEventsIn.data[j].event, LV2_EVENT_AUDIO_STAMP, fEventsIn.data[j].event->data);
  3376. lv2_event_begin(&fEventsIn.iters[j].event, fEventsIn.data[j].event);
  3377. }
  3378. else if (fEventsIn.data[j].type & CARLA_EVENT_DATA_MIDI_LL)
  3379. {
  3380. fEventsIn.data[j].midi.event_count = 0;
  3381. fEventsIn.data[j].midi.size = 0;
  3382. fEventsIn.iters[j].midiState.position = eventTime;
  3383. }
  3384. }
  3385. for (uint32_t j=0; j < fEventsOut.count; ++j)
  3386. {
  3387. if (fEventsOut.data[j].type & CARLA_EVENT_DATA_ATOM)
  3388. {
  3389. lv2_atom_buffer_reset(fEventsOut.data[j].atom, false);
  3390. }
  3391. else if (fEventsOut.data[j].type & CARLA_EVENT_DATA_EVENT)
  3392. {
  3393. lv2_event_buffer_reset(fEventsOut.data[j].event, LV2_EVENT_AUDIO_STAMP, fEventsOut.data[j].event->data);
  3394. }
  3395. else if (fEventsOut.data[j].type & CARLA_EVENT_DATA_MIDI_LL)
  3396. {
  3397. // not needed
  3398. }
  3399. }
  3400. }
  3401. else
  3402. {
  3403. startTime += timeOffset;
  3404. }
  3405. }
  3406. switch (event.type)
  3407. {
  3408. case kEngineEventTypeNull:
  3409. break;
  3410. case kEngineEventTypeControl: {
  3411. EngineControlEvent& ctrlEvent(event.ctrl);
  3412. switch (ctrlEvent.type)
  3413. {
  3414. case kEngineControlEventTypeNull:
  3415. break;
  3416. case kEngineControlEventTypeParameter: {
  3417. float value;
  3418. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  3419. // non-midi
  3420. if (event.channel == kEngineEventNonMidiChannel)
  3421. {
  3422. const uint32_t k = ctrlEvent.param;
  3423. CARLA_SAFE_ASSERT_CONTINUE(k < pData->param.count);
  3424. ctrlEvent.handled = true;
  3425. value = pData->param.getFinalUnnormalizedValue(k, ctrlEvent.normalizedValue);
  3426. setParameterValueRT(k, value, event.time, true);
  3427. continue;
  3428. }
  3429. // Control backend stuff
  3430. if (event.channel == pData->ctrlChannel)
  3431. {
  3432. if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_DRYWET) != 0)
  3433. {
  3434. ctrlEvent.handled = true;
  3435. value = ctrlEvent.normalizedValue;
  3436. setDryWetRT(value, true);
  3437. }
  3438. else if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_VOLUME) != 0)
  3439. {
  3440. ctrlEvent.handled = true;
  3441. value = ctrlEvent.normalizedValue*127.0f/100.0f;
  3442. setVolumeRT(value, true);
  3443. }
  3444. else if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_BALANCE) != 0)
  3445. {
  3446. float left, right;
  3447. value = ctrlEvent.normalizedValue/0.5f - 1.0f;
  3448. if (value < 0.0f)
  3449. {
  3450. left = -1.0f;
  3451. right = (value*2.0f)+1.0f;
  3452. }
  3453. else if (value > 0.0f)
  3454. {
  3455. left = (value*2.0f)-1.0f;
  3456. right = 1.0f;
  3457. }
  3458. else
  3459. {
  3460. left = -1.0f;
  3461. right = 1.0f;
  3462. }
  3463. ctrlEvent.handled = true;
  3464. setBalanceLeftRT(left, true);
  3465. setBalanceRightRT(right, true);
  3466. }
  3467. }
  3468. #endif
  3469. // Control plugin parameters
  3470. uint32_t k;
  3471. for (k=0; k < pData->param.count; ++k)
  3472. {
  3473. if (pData->param.data[k].midiChannel != event.channel)
  3474. continue;
  3475. if (pData->param.data[k].mappedControlIndex != ctrlEvent.param)
  3476. continue;
  3477. if (pData->param.data[k].type != PARAMETER_INPUT)
  3478. continue;
  3479. if ((pData->param.data[k].hints & PARAMETER_IS_AUTOMATABLE) == 0)
  3480. continue;
  3481. ctrlEvent.handled = true;
  3482. if (pData->param.data[k].mappedFlags & PARAMETER_MAPPING_MIDI_DELTA)
  3483. value = pData->param.getFinalValueWithMidiDelta(k, fParamBuffers[k], ctrlEvent.midiValue);
  3484. else
  3485. value = pData->param.getFinalUnnormalizedValue(k, ctrlEvent.normalizedValue);
  3486. setParameterValueRT(k, value, event.time, true);
  3487. }
  3488. if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param < MAX_MIDI_VALUE)
  3489. {
  3490. uint8_t midiData[3];
  3491. midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
  3492. midiData[1] = uint8_t(ctrlEvent.param);
  3493. midiData[2] = uint8_t(ctrlEvent.normalizedValue*127.0f + 0.5f);
  3494. const uint32_t mtime(isSampleAccurate ? startTime : eventTime);
  3495. if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
  3496. lv2_atom_buffer_write(&fEventsIn.iters[fEventsIn.ctrlIndex].atom, mtime, 0, kUridMidiEvent, 3, midiData);
  3497. else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
  3498. lv2_event_write(&fEventsIn.iters[fEventsIn.ctrlIndex].event, mtime, 0, kUridMidiEvent, 3, midiData);
  3499. else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
  3500. lv2midi_put_event(&fEventsIn.iters[fEventsIn.ctrlIndex].midiState, mtime, 3, midiData);
  3501. }
  3502. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  3503. if (! ctrlEvent.handled)
  3504. checkForMidiLearn(event);
  3505. #endif
  3506. break;
  3507. } // case kEngineControlEventTypeParameter
  3508. case kEngineControlEventTypeMidiBank:
  3509. if (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES)
  3510. {
  3511. if (event.channel == pData->ctrlChannel)
  3512. nextBankId = ctrlEvent.param;
  3513. }
  3514. else if (pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES)
  3515. {
  3516. uint8_t midiData[3];
  3517. midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
  3518. midiData[1] = MIDI_CONTROL_BANK_SELECT;
  3519. midiData[2] = uint8_t(ctrlEvent.param);
  3520. const uint32_t mtime(isSampleAccurate ? startTime : eventTime);
  3521. if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
  3522. lv2_atom_buffer_write(&fEventsIn.iters[fEventsIn.ctrlIndex].atom, mtime, 0, kUridMidiEvent, 3, midiData);
  3523. else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
  3524. lv2_event_write(&fEventsIn.iters[fEventsIn.ctrlIndex].event, mtime, 0, kUridMidiEvent, 3, midiData);
  3525. else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
  3526. lv2midi_put_event(&fEventsIn.iters[fEventsIn.ctrlIndex].midiState, mtime, 3, midiData);
  3527. }
  3528. break;
  3529. case kEngineControlEventTypeMidiProgram:
  3530. if (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES)
  3531. {
  3532. if (event.channel == pData->ctrlChannel)
  3533. {
  3534. const uint32_t nextProgramId(ctrlEvent.param);
  3535. for (uint32_t k=0; k < pData->midiprog.count; ++k)
  3536. {
  3537. if (pData->midiprog.data[k].bank == nextBankId && pData->midiprog.data[k].program == nextProgramId)
  3538. {
  3539. setMidiProgramRT(k, true);
  3540. break;
  3541. }
  3542. }
  3543. }
  3544. }
  3545. else if (pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES)
  3546. {
  3547. uint8_t midiData[2];
  3548. midiData[0] = uint8_t(MIDI_STATUS_PROGRAM_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
  3549. midiData[1] = uint8_t(ctrlEvent.param);
  3550. const uint32_t mtime(isSampleAccurate ? startTime : eventTime);
  3551. if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
  3552. lv2_atom_buffer_write(&fEventsIn.iters[fEventsIn.ctrlIndex].atom, mtime, 0, kUridMidiEvent, 2, midiData);
  3553. else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
  3554. lv2_event_write(&fEventsIn.iters[fEventsIn.ctrlIndex].event, mtime, 0, kUridMidiEvent, 2, midiData);
  3555. else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
  3556. lv2midi_put_event(&fEventsIn.iters[fEventsIn.ctrlIndex].midiState, mtime, 2, midiData);
  3557. }
  3558. break;
  3559. case kEngineControlEventTypeAllSoundOff:
  3560. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  3561. {
  3562. const uint32_t mtime(isSampleAccurate ? startTime : eventTime);
  3563. uint8_t midiData[3];
  3564. midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
  3565. midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF;
  3566. midiData[2] = 0;
  3567. if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
  3568. lv2_atom_buffer_write(&fEventsIn.iters[fEventsIn.ctrlIndex].atom, mtime, 0, kUridMidiEvent, 3, midiData);
  3569. else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
  3570. lv2_event_write(&fEventsIn.iters[fEventsIn.ctrlIndex].event, mtime, 0, kUridMidiEvent, 3, midiData);
  3571. else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
  3572. lv2midi_put_event(&fEventsIn.iters[fEventsIn.ctrlIndex].midiState, mtime, 3, midiData);
  3573. }
  3574. break;
  3575. case kEngineControlEventTypeAllNotesOff:
  3576. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  3577. {
  3578. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  3579. if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
  3580. {
  3581. allNotesOffSent = true;
  3582. postponeRtAllNotesOff();
  3583. }
  3584. #endif
  3585. const uint32_t mtime(isSampleAccurate ? startTime : eventTime);
  3586. uint8_t midiData[3];
  3587. midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
  3588. midiData[1] = MIDI_CONTROL_ALL_NOTES_OFF;
  3589. midiData[2] = 0;
  3590. if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
  3591. lv2_atom_buffer_write(&fEventsIn.iters[fEventsIn.ctrlIndex].atom, mtime, 0, kUridMidiEvent, 3, midiData);
  3592. else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
  3593. lv2_event_write(&fEventsIn.iters[fEventsIn.ctrlIndex].event, mtime, 0, kUridMidiEvent, 3, midiData);
  3594. else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
  3595. lv2midi_put_event(&fEventsIn.iters[fEventsIn.ctrlIndex].midiState, mtime, 3, midiData);
  3596. }
  3597. break;
  3598. } // switch (ctrlEvent.type)
  3599. break;
  3600. } // case kEngineEventTypeControl
  3601. case kEngineEventTypeMidi: {
  3602. const EngineMidiEvent& midiEvent(event.midi);
  3603. const uint8_t* const midiData = midiEvent.size > EngineMidiEvent::kDataSize ? midiEvent.dataExt : midiEvent.data;
  3604. uint8_t status = uint8_t(MIDI_GET_STATUS_FROM_DATA(midiData));
  3605. if ((status == MIDI_STATUS_NOTE_OFF || status == MIDI_STATUS_NOTE_ON) && (pData->options & PLUGIN_OPTION_SKIP_SENDING_NOTES))
  3606. continue;
  3607. if (status == MIDI_STATUS_CHANNEL_PRESSURE && (pData->options & PLUGIN_OPTION_SEND_CHANNEL_PRESSURE) == 0)
  3608. continue;
  3609. if (status == MIDI_STATUS_CONTROL_CHANGE && (pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) == 0)
  3610. continue;
  3611. if (status == MIDI_STATUS_POLYPHONIC_AFTERTOUCH && (pData->options & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) == 0)
  3612. continue;
  3613. if (status == MIDI_STATUS_PITCH_WHEEL_CONTROL && (pData->options & PLUGIN_OPTION_SEND_PITCHBEND) == 0)
  3614. continue;
  3615. // Fix bad note-off (per LV2 spec)
  3616. if (status == MIDI_STATUS_NOTE_ON && midiData[2] == 0)
  3617. status = MIDI_STATUS_NOTE_OFF;
  3618. const uint32_t j = fEventsIn.ctrlIndex;
  3619. const uint32_t mtime = isSampleAccurate ? startTime : eventTime;
  3620. // put back channel in data
  3621. uint8_t midiData2[4]; // FIXME
  3622. if (midiEvent.size > 4)
  3623. continue;
  3624. {
  3625. midiData2[0] = uint8_t(status | (event.channel & MIDI_CHANNEL_BIT));
  3626. std::memcpy(midiData2+1, midiData+1, static_cast<std::size_t>(midiEvent.size-1));
  3627. }
  3628. if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
  3629. lv2_atom_buffer_write(&fEventsIn.iters[j].atom, mtime, 0, kUridMidiEvent, midiEvent.size, midiData2);
  3630. else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
  3631. lv2_event_write(&fEventsIn.iters[j].event, mtime, 0, kUridMidiEvent, midiEvent.size, midiData2);
  3632. else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
  3633. lv2midi_put_event(&fEventsIn.iters[j].midiState, mtime, midiEvent.size, midiData2);
  3634. if (status == MIDI_STATUS_NOTE_ON)
  3635. {
  3636. pData->postponeNoteOnRtEvent(true, event.channel, midiData[1], midiData[2]);
  3637. }
  3638. else if (status == MIDI_STATUS_NOTE_OFF)
  3639. {
  3640. pData->postponeNoteOffRtEvent(true, event.channel, midiData[1]);
  3641. }
  3642. } break;
  3643. } // switch (event.type)
  3644. }
  3645. pData->postRtEvents.trySplice();
  3646. if (frames > timeOffset)
  3647. processSingle(audioIn, audioOut, cvIn, cvOut, frames - timeOffset, timeOffset);
  3648. } // End of Event Input and Processing
  3649. // --------------------------------------------------------------------------------------------------------
  3650. // Plugin processing (no events)
  3651. else
  3652. {
  3653. processSingle(audioIn, audioOut, cvIn, cvOut, frames, 0);
  3654. } // End of Plugin processing (no events)
  3655. // --------------------------------------------------------------------------------------------------------
  3656. // Final work
  3657. if (fEventsIn.ctrl != nullptr && fExt.worker != nullptr && fAtomBufferWorkerResp.tryLock())
  3658. {
  3659. if (fAtomBufferWorkerResp.isDataAvailableForReading())
  3660. {
  3661. uint32_t portIndex;
  3662. LV2_Atom* const atom = fAtomBufferRealtime;
  3663. atom->size = fAtomBufferRealtimeSize;
  3664. for (; fAtomBufferWorkerResp.get(portIndex, atom); atom->size = fAtomBufferRealtimeSize)
  3665. {
  3666. CARLA_SAFE_ASSERT_CONTINUE(atom->type == kUridCarlaAtomWorkerResp);
  3667. fExt.worker->work_response(fHandle, atom->size, LV2_ATOM_BODY_CONST(atom));
  3668. }
  3669. }
  3670. fAtomBufferWorkerResp.unlock();
  3671. }
  3672. if (fExt.worker != nullptr && fExt.worker->end_run != nullptr)
  3673. {
  3674. fExt.worker->end_run(fHandle);
  3675. if (fHandle2 != nullptr)
  3676. fExt.worker->end_run(fHandle2);
  3677. }
  3678. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  3679. // --------------------------------------------------------------------------------------------------------
  3680. // Control Output
  3681. if (pData->event.portOut != nullptr)
  3682. {
  3683. uint8_t channel;
  3684. uint16_t param;
  3685. float value;
  3686. for (uint32_t k=0; k < pData->param.count; ++k)
  3687. {
  3688. if (pData->param.data[k].type != PARAMETER_OUTPUT)
  3689. continue;
  3690. if (fStrictBounds >= 0 && (pData->param.data[k].hints & PARAMETER_IS_STRICT_BOUNDS) != 0)
  3691. // plugin is responsible to ensure correct bounds
  3692. pData->param.ranges[k].fixValue(fParamBuffers[k]);
  3693. if (pData->param.data[k].mappedControlIndex > 0)
  3694. {
  3695. channel = pData->param.data[k].midiChannel;
  3696. param = static_cast<uint16_t>(pData->param.data[k].mappedControlIndex);
  3697. value = pData->param.ranges[k].getNormalizedValue(fParamBuffers[k]);
  3698. pData->event.portOut->writeControlEvent(0, channel, kEngineControlEventTypeParameter,
  3699. param, -1, value);
  3700. }
  3701. }
  3702. } // End of Control Output
  3703. #endif
  3704. // --------------------------------------------------------------------------------------------------------
  3705. // Events/MIDI Output
  3706. for (uint32_t i=0; i < fEventsOut.count; ++i)
  3707. {
  3708. uint32_t lastFrame = 0;
  3709. Lv2EventData& evData(fEventsOut.data[i]);
  3710. if (evData.type & CARLA_EVENT_DATA_ATOM)
  3711. {
  3712. const LV2_Atom_Event* ev;
  3713. LV2_Atom_Buffer_Iterator iter;
  3714. uint8_t* data;
  3715. lv2_atom_buffer_begin(&iter, evData.atom);
  3716. for (;;)
  3717. {
  3718. data = nullptr;
  3719. ev = lv2_atom_buffer_get(&iter, &data);
  3720. if (ev == nullptr || ev->body.size == 0 || data == nullptr)
  3721. break;
  3722. if (ev->body.type == kUridMidiEvent)
  3723. {
  3724. if (evData.port != nullptr)
  3725. {
  3726. CARLA_SAFE_ASSERT_CONTINUE(ev->time.frames >= 0);
  3727. CARLA_SAFE_ASSERT_CONTINUE(ev->body.size < 0xFF);
  3728. uint32_t currentFrame = static_cast<uint32_t>(ev->time.frames);
  3729. if (currentFrame < lastFrame)
  3730. currentFrame = lastFrame;
  3731. else if (currentFrame >= frames)
  3732. currentFrame = frames - 1;
  3733. evData.port->writeMidiEvent(currentFrame, static_cast<uint8_t>(ev->body.size), data);
  3734. }
  3735. }
  3736. else if (fAtomBufferUiOutTmpData != nullptr)
  3737. {
  3738. fAtomBufferUiOut.put(&ev->body, evData.rindex);
  3739. }
  3740. lv2_atom_buffer_increment(&iter);
  3741. }
  3742. }
  3743. else if ((evData.type & CARLA_EVENT_DATA_EVENT) != 0 && evData.port != nullptr)
  3744. {
  3745. const LV2_Event* ev;
  3746. LV2_Event_Iterator iter;
  3747. uint8_t* data;
  3748. lv2_event_begin(&iter, evData.event);
  3749. for (;;)
  3750. {
  3751. data = nullptr;
  3752. ev = lv2_event_get(&iter, &data);
  3753. if (ev == nullptr || data == nullptr)
  3754. break;
  3755. uint32_t currentFrame = ev->frames;
  3756. if (currentFrame < lastFrame)
  3757. currentFrame = lastFrame;
  3758. else if (currentFrame >= frames)
  3759. currentFrame = frames - 1;
  3760. if (ev->type == kUridMidiEvent)
  3761. {
  3762. CARLA_SAFE_ASSERT_CONTINUE(ev->size < 0xFF);
  3763. evData.port->writeMidiEvent(currentFrame, static_cast<uint8_t>(ev->size), data);
  3764. }
  3765. lv2_event_increment(&iter);
  3766. }
  3767. }
  3768. else if ((evData.type & CARLA_EVENT_DATA_MIDI_LL) != 0 && evData.port != nullptr)
  3769. {
  3770. LV2_MIDIState state = { &evData.midi, frames, 0 };
  3771. uint32_t eventSize;
  3772. double eventTime;
  3773. uchar* eventData;
  3774. for (;;)
  3775. {
  3776. eventSize = 0;
  3777. eventTime = 0.0;
  3778. eventData = nullptr;
  3779. lv2midi_get_event(&state, &eventTime, &eventSize, &eventData);
  3780. if (eventData == nullptr || eventSize == 0)
  3781. break;
  3782. CARLA_SAFE_ASSERT_CONTINUE(eventSize < 0xFF);
  3783. CARLA_SAFE_ASSERT_CONTINUE(eventTime >= 0.0);
  3784. evData.port->writeMidiEvent(static_cast<uint32_t>(eventTime), static_cast<uint8_t>(eventSize), eventData);
  3785. lv2midi_step(&state);
  3786. }
  3787. }
  3788. }
  3789. fFirstActive = false;
  3790. // --------------------------------------------------------------------------------------------------------
  3791. }
  3792. bool processSingle(const float* const* const audioIn, float** const audioOut,
  3793. const float* const* const cvIn, float** const cvOut,
  3794. const uint32_t frames, const uint32_t timeOffset)
  3795. {
  3796. CARLA_SAFE_ASSERT_RETURN(frames > 0, false);
  3797. if (pData->audioIn.count > 0)
  3798. {
  3799. CARLA_SAFE_ASSERT_RETURN(audioIn != nullptr, false);
  3800. CARLA_SAFE_ASSERT_RETURN(fAudioInBuffers != nullptr, false);
  3801. }
  3802. if (pData->audioOut.count > 0)
  3803. {
  3804. CARLA_SAFE_ASSERT_RETURN(audioOut != nullptr, false);
  3805. CARLA_SAFE_ASSERT_RETURN(fAudioOutBuffers != nullptr, false);
  3806. }
  3807. if (pData->cvIn.count > 0)
  3808. {
  3809. CARLA_SAFE_ASSERT_RETURN(cvIn != nullptr, false);
  3810. }
  3811. if (pData->cvOut.count > 0)
  3812. {
  3813. CARLA_SAFE_ASSERT_RETURN(cvOut != nullptr, false);
  3814. }
  3815. // --------------------------------------------------------------------------------------------------------
  3816. // Try lock, silence otherwise
  3817. #ifndef STOAT_TEST_BUILD
  3818. if (pData->engine->isOffline())
  3819. {
  3820. pData->singleMutex.lock();
  3821. }
  3822. else
  3823. #endif
  3824. if (! pData->singleMutex.tryLock())
  3825. {
  3826. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  3827. {
  3828. for (uint32_t k=0; k < frames; ++k)
  3829. audioOut[i][k+timeOffset] = 0.0f;
  3830. }
  3831. for (uint32_t i=0; i < pData->cvOut.count; ++i)
  3832. {
  3833. for (uint32_t k=0; k < frames; ++k)
  3834. cvOut[i][k+timeOffset] = 0.0f;
  3835. }
  3836. return false;
  3837. }
  3838. // --------------------------------------------------------------------------------------------------------
  3839. // Set audio buffers
  3840. for (uint32_t i=0; i < pData->audioIn.count; ++i)
  3841. carla_copyFloats(fAudioInBuffers[i], audioIn[i]+timeOffset, frames);
  3842. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  3843. carla_zeroFloats(fAudioOutBuffers[i], frames);
  3844. // --------------------------------------------------------------------------------------------------------
  3845. // Set CV buffers
  3846. for (uint32_t i=0; i < pData->cvIn.count; ++i)
  3847. carla_copyFloats(fCvInBuffers[i], cvIn[i]+timeOffset, frames);
  3848. for (uint32_t i=0; i < pData->cvOut.count; ++i)
  3849. carla_zeroFloats(fCvOutBuffers[i], frames);
  3850. // --------------------------------------------------------------------------------------------------------
  3851. // Run plugin
  3852. fDescriptor->run(fHandle, frames);
  3853. if (fHandle2 != nullptr)
  3854. fDescriptor->run(fHandle2, frames);
  3855. // --------------------------------------------------------------------------------------------------------
  3856. // Handle trigger parameters
  3857. for (uint32_t k=0; k < pData->param.count; ++k)
  3858. {
  3859. if (pData->param.data[k].type != PARAMETER_INPUT)
  3860. continue;
  3861. if (pData->param.data[k].hints & PARAMETER_IS_TRIGGER)
  3862. {
  3863. if (carla_isNotEqual(fParamBuffers[k], pData->param.ranges[k].def))
  3864. {
  3865. fParamBuffers[k] = pData->param.ranges[k].def;
  3866. pData->postponeParameterChangeRtEvent(true, static_cast<int32_t>(k), fParamBuffers[k]);
  3867. }
  3868. }
  3869. }
  3870. pData->postRtEvents.trySplice();
  3871. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  3872. // --------------------------------------------------------------------------------------------------------
  3873. // Post-processing (dry/wet, volume and balance)
  3874. {
  3875. const bool doDryWet = (pData->hints & PLUGIN_CAN_DRYWET) != 0 && carla_isNotEqual(pData->postProc.dryWet, 1.0f);
  3876. const bool doBalance = (pData->hints & PLUGIN_CAN_BALANCE) != 0 && ! (carla_isEqual(pData->postProc.balanceLeft, -1.0f) && carla_isEqual(pData->postProc.balanceRight, 1.0f));
  3877. const bool isMono = (pData->audioIn.count == 1);
  3878. bool isPair;
  3879. float bufValue;
  3880. float* const oldBufLeft = pData->postProc.extraBuffer;
  3881. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  3882. {
  3883. // Dry/Wet
  3884. if (doDryWet)
  3885. {
  3886. const uint32_t c = isMono ? 0 : i;
  3887. for (uint32_t k=0; k < frames; ++k)
  3888. {
  3889. # ifndef BUILD_BRIDGE
  3890. if (k < pData->latency.frames && pData->latency.buffers != nullptr)
  3891. bufValue = pData->latency.buffers[c][k];
  3892. else if (pData->latency.frames < frames)
  3893. bufValue = fAudioInBuffers[c][k-pData->latency.frames];
  3894. else
  3895. # endif
  3896. bufValue = fAudioInBuffers[c][k];
  3897. fAudioOutBuffers[i][k] = (fAudioOutBuffers[i][k] * pData->postProc.dryWet) + (bufValue * (1.0f - pData->postProc.dryWet));
  3898. }
  3899. }
  3900. // Balance
  3901. if (doBalance)
  3902. {
  3903. isPair = (i % 2 == 0);
  3904. if (isPair)
  3905. {
  3906. CARLA_ASSERT(i+1 < pData->audioOut.count);
  3907. carla_copyFloats(oldBufLeft, fAudioOutBuffers[i], frames);
  3908. }
  3909. float balRangeL = (pData->postProc.balanceLeft + 1.0f)/2.0f;
  3910. float balRangeR = (pData->postProc.balanceRight + 1.0f)/2.0f;
  3911. for (uint32_t k=0; k < frames; ++k)
  3912. {
  3913. if (isPair)
  3914. {
  3915. // left
  3916. fAudioOutBuffers[i][k] = oldBufLeft[k] * (1.0f - balRangeL);
  3917. fAudioOutBuffers[i][k] += fAudioOutBuffers[i+1][k] * (1.0f - balRangeR);
  3918. }
  3919. else
  3920. {
  3921. // right
  3922. fAudioOutBuffers[i][k] = fAudioOutBuffers[i][k] * balRangeR;
  3923. fAudioOutBuffers[i][k] += oldBufLeft[k] * balRangeL;
  3924. }
  3925. }
  3926. }
  3927. // Volume (and buffer copy)
  3928. {
  3929. for (uint32_t k=0; k < frames; ++k)
  3930. audioOut[i][k+timeOffset] = fAudioOutBuffers[i][k] * pData->postProc.volume;
  3931. }
  3932. }
  3933. } // End of Post-processing
  3934. # ifndef BUILD_BRIDGE
  3935. // --------------------------------------------------------------------------------------------------------
  3936. // Save latency values for next callback
  3937. if (pData->latency.frames != 0 && pData->latency.buffers != nullptr)
  3938. {
  3939. CARLA_SAFE_ASSERT(timeOffset == 0);
  3940. const uint32_t latframes = pData->latency.frames;
  3941. if (latframes <= frames)
  3942. {
  3943. for (uint32_t i=0; i < pData->audioIn.count; ++i)
  3944. carla_copyFloats(pData->latency.buffers[i], audioIn[i]+(frames-latframes), latframes);
  3945. }
  3946. else
  3947. {
  3948. const uint32_t diff = latframes - frames;
  3949. for (uint32_t i=0, k; i<pData->audioIn.count; ++i)
  3950. {
  3951. // push back buffer by 'frames'
  3952. for (k=0; k < diff; ++k)
  3953. pData->latency.buffers[i][k] = pData->latency.buffers[i][k+frames];
  3954. // put current input at the end
  3955. for (uint32_t j=0; k < latframes; ++j, ++k)
  3956. pData->latency.buffers[i][k] = audioIn[i][j];
  3957. }
  3958. }
  3959. }
  3960. # endif
  3961. #else // BUILD_BRIDGE_ALTERNATIVE_ARCH
  3962. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  3963. {
  3964. for (uint32_t k=0; k < frames; ++k)
  3965. audioOut[i][k+timeOffset] = fAudioOutBuffers[i][k];
  3966. }
  3967. #endif
  3968. for (uint32_t i=0; i < pData->cvOut.count; ++i)
  3969. {
  3970. for (uint32_t k=0; k < frames; ++k)
  3971. cvOut[i][k+timeOffset] = fCvOutBuffers[i][k];
  3972. }
  3973. // --------------------------------------------------------------------------------------------------------
  3974. pData->singleMutex.unlock();
  3975. return true;
  3976. }
  3977. void bufferSizeChanged(const uint32_t newBufferSize) override
  3978. {
  3979. CARLA_ASSERT_INT(newBufferSize > 0, newBufferSize);
  3980. carla_debug("CarlaPluginLV2::bufferSizeChanged(%i) - start", newBufferSize);
  3981. for (uint32_t i=0; i < pData->audioIn.count; ++i)
  3982. {
  3983. if (fAudioInBuffers[i] != nullptr)
  3984. delete[] fAudioInBuffers[i];
  3985. fAudioInBuffers[i] = new float[newBufferSize];
  3986. }
  3987. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  3988. {
  3989. if (fAudioOutBuffers[i] != nullptr)
  3990. delete[] fAudioOutBuffers[i];
  3991. fAudioOutBuffers[i] = new float[newBufferSize];
  3992. }
  3993. if (fHandle2 == nullptr)
  3994. {
  3995. for (uint32_t i=0; i < pData->audioIn.count; ++i)
  3996. {
  3997. CARLA_ASSERT(fAudioInBuffers[i] != nullptr);
  3998. fDescriptor->connect_port(fHandle, pData->audioIn.ports[i].rindex, fAudioInBuffers[i]);
  3999. }
  4000. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  4001. {
  4002. CARLA_ASSERT(fAudioOutBuffers[i] != nullptr);
  4003. fDescriptor->connect_port(fHandle, pData->audioOut.ports[i].rindex, fAudioOutBuffers[i]);
  4004. }
  4005. }
  4006. else
  4007. {
  4008. if (pData->audioIn.count > 0)
  4009. {
  4010. CARLA_ASSERT(pData->audioIn.count == 2);
  4011. CARLA_ASSERT(fAudioInBuffers[0] != nullptr);
  4012. CARLA_ASSERT(fAudioInBuffers[1] != nullptr);
  4013. fDescriptor->connect_port(fHandle, pData->audioIn.ports[0].rindex, fAudioInBuffers[0]);
  4014. fDescriptor->connect_port(fHandle2, pData->audioIn.ports[1].rindex, fAudioInBuffers[1]);
  4015. }
  4016. if (pData->audioOut.count > 0)
  4017. {
  4018. CARLA_ASSERT(pData->audioOut.count == 2);
  4019. CARLA_ASSERT(fAudioOutBuffers[0] != nullptr);
  4020. CARLA_ASSERT(fAudioOutBuffers[1] != nullptr);
  4021. fDescriptor->connect_port(fHandle, pData->audioOut.ports[0].rindex, fAudioOutBuffers[0]);
  4022. fDescriptor->connect_port(fHandle2, pData->audioOut.ports[1].rindex, fAudioOutBuffers[1]);
  4023. }
  4024. }
  4025. for (uint32_t i=0; i < pData->cvIn.count; ++i)
  4026. {
  4027. if (fCvInBuffers[i] != nullptr)
  4028. delete[] fCvInBuffers[i];
  4029. fCvInBuffers[i] = new float[newBufferSize];
  4030. fDescriptor->connect_port(fHandle, pData->cvIn.ports[i].rindex, fCvInBuffers[i]);
  4031. if (fHandle2 != nullptr)
  4032. fDescriptor->connect_port(fHandle2, pData->cvIn.ports[i].rindex, fCvInBuffers[i]);
  4033. }
  4034. for (uint32_t i=0; i < pData->cvOut.count; ++i)
  4035. {
  4036. if (fCvOutBuffers[i] != nullptr)
  4037. delete[] fCvOutBuffers[i];
  4038. fCvOutBuffers[i] = new float[newBufferSize];
  4039. fDescriptor->connect_port(fHandle, pData->cvOut.ports[i].rindex, fCvOutBuffers[i]);
  4040. if (fHandle2 != nullptr)
  4041. fDescriptor->connect_port(fHandle2, pData->cvOut.ports[i].rindex, fCvOutBuffers[i]);
  4042. }
  4043. const int newBufferSizeInt(static_cast<int>(newBufferSize));
  4044. if (fLv2Options.maxBufferSize != newBufferSizeInt || (fLv2Options.minBufferSize != 1 && fLv2Options.minBufferSize != newBufferSizeInt))
  4045. {
  4046. fLv2Options.maxBufferSize = fLv2Options.nominalBufferSize = newBufferSizeInt;
  4047. if (fLv2Options.minBufferSize != 1)
  4048. fLv2Options.minBufferSize = newBufferSizeInt;
  4049. if (fExt.options != nullptr && fExt.options->set != nullptr)
  4050. {
  4051. LV2_Options_Option options[4];
  4052. carla_zeroStructs(options, 4);
  4053. carla_copyStruct(options[0], fLv2Options.opts[CarlaPluginLV2Options::MaxBlockLenth]);
  4054. carla_copyStruct(options[1], fLv2Options.opts[CarlaPluginLV2Options::NominalBlockLenth]);
  4055. if (fLv2Options.minBufferSize != 1)
  4056. carla_copyStruct(options[2], fLv2Options.opts[CarlaPluginLV2Options::MinBlockLenth]);
  4057. fExt.options->set(fHandle, options);
  4058. }
  4059. }
  4060. carla_debug("CarlaPluginLV2::bufferSizeChanged(%i) - end", newBufferSize);
  4061. CarlaPlugin::bufferSizeChanged(newBufferSize);
  4062. }
  4063. void sampleRateChanged(const double newSampleRate) override
  4064. {
  4065. CARLA_ASSERT_INT(newSampleRate > 0.0, newSampleRate);
  4066. carla_debug("CarlaPluginLV2::sampleRateChanged(%g) - start", newSampleRate);
  4067. const float sampleRatef = static_cast<float>(newSampleRate);
  4068. if (carla_isNotEqual(fLv2Options.sampleRate, sampleRatef))
  4069. {
  4070. fLv2Options.sampleRate = sampleRatef;
  4071. if (fExt.options != nullptr && fExt.options->set != nullptr)
  4072. {
  4073. LV2_Options_Option options[2];
  4074. carla_copyStruct(options[0], fLv2Options.opts[CarlaPluginLV2Options::SampleRate]);
  4075. carla_zeroStruct(options[1]);
  4076. fExt.options->set(fHandle, options);
  4077. }
  4078. }
  4079. for (uint32_t k=0; k < pData->param.count; ++k)
  4080. {
  4081. if (pData->param.data[k].type != PARAMETER_INPUT)
  4082. continue;
  4083. if (pData->param.special[k] != PARAMETER_SPECIAL_SAMPLE_RATE)
  4084. continue;
  4085. fParamBuffers[k] = sampleRatef;
  4086. pData->postponeParameterChangeRtEvent(true, static_cast<int32_t>(k), fParamBuffers[k]);
  4087. break;
  4088. }
  4089. carla_debug("CarlaPluginLV2::sampleRateChanged(%g) - end", newSampleRate);
  4090. }
  4091. void offlineModeChanged(const bool isOffline) override
  4092. {
  4093. for (uint32_t k=0; k < pData->param.count; ++k)
  4094. {
  4095. if (pData->param.data[k].type == PARAMETER_INPUT && pData->param.special[k] == PARAMETER_SPECIAL_FREEWHEEL)
  4096. {
  4097. fParamBuffers[k] = isOffline ? pData->param.ranges[k].max : pData->param.ranges[k].min;
  4098. pData->postponeParameterChangeRtEvent(true, static_cast<int32_t>(k), fParamBuffers[k]);
  4099. break;
  4100. }
  4101. }
  4102. }
  4103. // -------------------------------------------------------------------
  4104. // Plugin buffers
  4105. void initBuffers() const noexcept override
  4106. {
  4107. fEventsIn.initBuffers();
  4108. fEventsOut.initBuffers();
  4109. CarlaPlugin::initBuffers();
  4110. }
  4111. void clearBuffers() noexcept override
  4112. {
  4113. carla_debug("CarlaPluginLV2::clearBuffers() - start");
  4114. if (fAudioInBuffers != nullptr)
  4115. {
  4116. for (uint32_t i=0; i < pData->audioIn.count; ++i)
  4117. {
  4118. if (fAudioInBuffers[i] != nullptr)
  4119. {
  4120. delete[] fAudioInBuffers[i];
  4121. fAudioInBuffers[i] = nullptr;
  4122. }
  4123. }
  4124. delete[] fAudioInBuffers;
  4125. fAudioInBuffers = nullptr;
  4126. }
  4127. if (fAudioOutBuffers != nullptr)
  4128. {
  4129. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  4130. {
  4131. if (fAudioOutBuffers[i] != nullptr)
  4132. {
  4133. delete[] fAudioOutBuffers[i];
  4134. fAudioOutBuffers[i] = nullptr;
  4135. }
  4136. }
  4137. delete[] fAudioOutBuffers;
  4138. fAudioOutBuffers = nullptr;
  4139. }
  4140. if (fCvInBuffers != nullptr)
  4141. {
  4142. for (uint32_t i=0; i < pData->cvIn.count; ++i)
  4143. {
  4144. if (fCvInBuffers[i] != nullptr)
  4145. {
  4146. delete[] fCvInBuffers[i];
  4147. fCvInBuffers[i] = nullptr;
  4148. }
  4149. }
  4150. delete[] fCvInBuffers;
  4151. fCvInBuffers = nullptr;
  4152. }
  4153. if (fCvOutBuffers != nullptr)
  4154. {
  4155. for (uint32_t i=0; i < pData->cvOut.count; ++i)
  4156. {
  4157. if (fCvOutBuffers[i] != nullptr)
  4158. {
  4159. delete[] fCvOutBuffers[i];
  4160. fCvOutBuffers[i] = nullptr;
  4161. }
  4162. }
  4163. delete[] fCvOutBuffers;
  4164. fCvOutBuffers = nullptr;
  4165. }
  4166. if (fParamBuffers != nullptr)
  4167. {
  4168. delete[] fParamBuffers;
  4169. fParamBuffers = nullptr;
  4170. }
  4171. fEventsIn.clear(pData->event.portIn);
  4172. fEventsOut.clear(pData->event.portOut);
  4173. CarlaPlugin::clearBuffers();
  4174. carla_debug("CarlaPluginLV2::clearBuffers() - end");
  4175. }
  4176. // -------------------------------------------------------------------
  4177. // Post-poned UI Stuff
  4178. void uiParameterChange(const uint32_t index, const float value) noexcept override
  4179. {
  4180. CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL || fFilePathURI.isNotEmpty(),);
  4181. CARLA_SAFE_ASSERT_RETURN(index < pData->param.count,);
  4182. CARLA_SAFE_ASSERT_RETURN(pData->param.data[index].rindex >= 0,);
  4183. #ifndef LV2_UIS_ONLY_INPROCESS
  4184. if (fUI.type == UI::TYPE_BRIDGE)
  4185. {
  4186. if (! fPipeServer.isPipeRunning())
  4187. return;
  4188. }
  4189. else
  4190. #endif
  4191. {
  4192. if (fUI.handle == nullptr)
  4193. return;
  4194. if (fUI.descriptor == nullptr || fUI.descriptor->port_event == nullptr)
  4195. return;
  4196. if (fNeedsUiClose)
  4197. return;
  4198. }
  4199. ParameterData& pdata(pData->param.data[index]);
  4200. if (pdata.hints & PARAMETER_IS_NOT_SAVED)
  4201. {
  4202. int32_t rindex = pdata.rindex;
  4203. CARLA_SAFE_ASSERT_RETURN(rindex - static_cast<int32_t>(fRdfDescriptor->PortCount) >= 0,);
  4204. rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount);
  4205. CARLA_SAFE_ASSERT_RETURN(rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount),);
  4206. const char* const uri = fRdfDescriptor->Parameters[rindex].URI;
  4207. #ifndef LV2_UIS_ONLY_INPROCESS
  4208. if (fUI.type == UI::TYPE_BRIDGE)
  4209. {
  4210. fPipeServer.writeLv2ParameterMessage(uri, value);
  4211. }
  4212. else
  4213. #endif
  4214. if (fEventsIn.ctrl != nullptr)
  4215. {
  4216. uint8_t atomBuf[256];
  4217. LV2_Atom_Forge atomForge;
  4218. initAtomForge(atomForge);
  4219. lv2_atom_forge_set_buffer(&atomForge, atomBuf, sizeof(atomBuf));
  4220. LV2_Atom_Forge_Frame forgeFrame;
  4221. lv2_atom_forge_object(&atomForge, &forgeFrame, kUridNull, kUridPatchSet);
  4222. lv2_atom_forge_key(&atomForge, kUridCarlaParameterChange);
  4223. lv2_atom_forge_bool(&atomForge, true);
  4224. lv2_atom_forge_key(&atomForge, kUridPatchProperty);
  4225. lv2_atom_forge_urid(&atomForge, getCustomURID(uri));
  4226. lv2_atom_forge_key(&atomForge, kUridPatchValue);
  4227. switch (fRdfDescriptor->Parameters[rindex].Type)
  4228. {
  4229. case LV2_PARAMETER_TYPE_BOOL:
  4230. lv2_atom_forge_bool(&atomForge, value > 0.5f);
  4231. break;
  4232. case LV2_PARAMETER_TYPE_INT:
  4233. lv2_atom_forge_int(&atomForge, static_cast<int32_t>(value + 0.5f));
  4234. break;
  4235. case LV2_PARAMETER_TYPE_LONG:
  4236. lv2_atom_forge_long(&atomForge, static_cast<int64_t>(value + 0.5f));
  4237. break;
  4238. case LV2_PARAMETER_TYPE_FLOAT:
  4239. lv2_atom_forge_float(&atomForge, value);
  4240. break;
  4241. case LV2_PARAMETER_TYPE_DOUBLE:
  4242. lv2_atom_forge_double(&atomForge, value);
  4243. break;
  4244. default:
  4245. carla_stderr2("uiParameterChange called for invalid parameter, abort!");
  4246. return;
  4247. }
  4248. lv2_atom_forge_pop(&atomForge, &forgeFrame);
  4249. LV2_Atom* const atom((LV2_Atom*)atomBuf);
  4250. CARLA_SAFE_ASSERT(atom->size < sizeof(atomBuf));
  4251. fUI.descriptor->port_event(fUI.handle,
  4252. fEventsIn.ctrl->rindex,
  4253. lv2_atom_total_size(atom),
  4254. kUridAtomTransferEvent,
  4255. atom);
  4256. }
  4257. }
  4258. else
  4259. {
  4260. #ifndef LV2_UIS_ONLY_INPROCESS
  4261. if (fUI.type == UI::TYPE_BRIDGE)
  4262. {
  4263. fPipeServer.writeControlMessage(static_cast<uint32_t>(pData->param.data[index].rindex), value);
  4264. }
  4265. else
  4266. #endif
  4267. {
  4268. fUI.descriptor->port_event(fUI.handle,
  4269. static_cast<uint32_t>(pData->param.data[index].rindex),
  4270. sizeof(float), kUridNull, &value);
  4271. }
  4272. }
  4273. }
  4274. void uiMidiProgramChange(const uint32_t index) noexcept override
  4275. {
  4276. CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL || fFilePathURI.isNotEmpty(),);
  4277. CARLA_SAFE_ASSERT_RETURN(index < pData->midiprog.count,);
  4278. #ifndef LV2_UIS_ONLY_INPROCESS
  4279. if (fUI.type == UI::TYPE_BRIDGE)
  4280. {
  4281. if (fPipeServer.isPipeRunning())
  4282. fPipeServer.writeMidiProgramMessage(pData->midiprog.data[index].bank, pData->midiprog.data[index].program);
  4283. }
  4284. else
  4285. #endif
  4286. {
  4287. if (fExt.uiprograms != nullptr && fExt.uiprograms->select_program != nullptr && ! fNeedsUiClose)
  4288. fExt.uiprograms->select_program(fUI.handle, pData->midiprog.data[index].bank, pData->midiprog.data[index].program);
  4289. }
  4290. }
  4291. void uiNoteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) noexcept override
  4292. {
  4293. CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL || fFilePathURI.isNotEmpty(),);
  4294. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  4295. CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,);
  4296. CARLA_SAFE_ASSERT_RETURN(velo > 0 && velo < MAX_MIDI_VALUE,);
  4297. #if 0
  4298. if (fUI.type == UI::TYPE_BRIDGE)
  4299. {
  4300. if (fPipeServer.isPipeRunning())
  4301. fPipeServer.writeMidiNoteMessage(false, channel, note, velo);
  4302. }
  4303. else
  4304. {
  4305. if (fUI.handle != nullptr && fUI.descriptor != nullptr && fUI.descriptor->port_event != nullptr && fEventsIn.ctrl != nullptr && ! fNeedsUiClose)
  4306. {
  4307. LV2_Atom_MidiEvent midiEv;
  4308. midiEv.atom.type = kUridMidiEvent;
  4309. midiEv.atom.size = 3;
  4310. midiEv.data[0] = uint8_t(MIDI_STATUS_NOTE_ON | (channel & MIDI_CHANNEL_BIT));
  4311. midiEv.data[1] = note;
  4312. midiEv.data[2] = velo;
  4313. fUI.descriptor->port_event(fUI.handle, fEventsIn.ctrl->rindex, lv2_atom_total_size(midiEv), kUridAtomTransferEvent, &midiEv);
  4314. }
  4315. }
  4316. #endif
  4317. }
  4318. void uiNoteOff(const uint8_t channel, const uint8_t note) noexcept override
  4319. {
  4320. CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL || fFilePathURI.isNotEmpty(),);
  4321. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  4322. CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,);
  4323. #if 0
  4324. if (fUI.type == UI::TYPE_BRIDGE)
  4325. {
  4326. if (fPipeServer.isPipeRunning())
  4327. fPipeServer.writeMidiNoteMessage(false, channel, note, 0);
  4328. }
  4329. else
  4330. {
  4331. if (fUI.handle != nullptr && fUI.descriptor != nullptr && fUI.descriptor->port_event != nullptr && fEventsIn.ctrl != nullptr && ! fNeedsUiClose)
  4332. {
  4333. LV2_Atom_MidiEvent midiEv;
  4334. midiEv.atom.type = kUridMidiEvent;
  4335. midiEv.atom.size = 3;
  4336. midiEv.data[0] = uint8_t(MIDI_STATUS_NOTE_OFF | (channel & MIDI_CHANNEL_BIT));
  4337. midiEv.data[1] = note;
  4338. midiEv.data[2] = 0;
  4339. fUI.descriptor->port_event(fUI.handle, fEventsIn.ctrl->rindex, lv2_atom_total_size(midiEv), kUridAtomTransferEvent, &midiEv);
  4340. }
  4341. }
  4342. #endif
  4343. }
  4344. // -------------------------------------------------------------------
  4345. // Internal helper functions
  4346. void cloneLV2Files(const CarlaPlugin& other) override
  4347. {
  4348. CARLA_SAFE_ASSERT_RETURN(other.getType() == PLUGIN_LV2,);
  4349. const CarlaPluginLV2& otherLV2((const CarlaPluginLV2&)other);
  4350. const File tmpDir(handleStateMapToAbsolutePath(false, false, true, "."));
  4351. if (tmpDir.exists())
  4352. tmpDir.deleteRecursively();
  4353. const File otherStateDir(otherLV2.handleStateMapToAbsolutePath(false, false, false, "."));
  4354. if (otherStateDir.exists())
  4355. otherStateDir.copyDirectoryTo(tmpDir);
  4356. const File otherTmpDir(otherLV2.handleStateMapToAbsolutePath(false, false, true, "."));
  4357. if (otherTmpDir.exists())
  4358. otherTmpDir.copyDirectoryTo(tmpDir);
  4359. }
  4360. void restoreLV2State(const bool temporary) noexcept override
  4361. {
  4362. if (fExt.state == nullptr || fExt.state->restore == nullptr)
  4363. return;
  4364. if (! temporary)
  4365. {
  4366. const File tmpDir(handleStateMapToAbsolutePath(false, false, true, "."));
  4367. if (tmpDir.exists())
  4368. tmpDir.deleteRecursively();
  4369. }
  4370. LV2_State_Status status = LV2_STATE_ERR_UNKNOWN;
  4371. {
  4372. const ScopedSingleProcessLocker spl(this, !fHasThreadSafeRestore);
  4373. try {
  4374. status = fExt.state->restore(fHandle,
  4375. carla_lv2_state_retrieve,
  4376. this,
  4377. LV2_STATE_IS_POD,
  4378. temporary ? fFeatures : fStateFeatures);
  4379. } catch(...) {}
  4380. if (fHandle2 != nullptr)
  4381. {
  4382. try {
  4383. fExt.state->restore(fHandle,
  4384. carla_lv2_state_retrieve,
  4385. this,
  4386. LV2_STATE_IS_POD,
  4387. temporary ? fFeatures : fStateFeatures);
  4388. } catch(...) {}
  4389. }
  4390. }
  4391. switch (status)
  4392. {
  4393. case LV2_STATE_SUCCESS:
  4394. carla_debug("CarlaPluginLV2::updateLV2State() - success");
  4395. break;
  4396. case LV2_STATE_ERR_UNKNOWN:
  4397. carla_stderr("CarlaPluginLV2::updateLV2State() - unknown error");
  4398. break;
  4399. case LV2_STATE_ERR_BAD_TYPE:
  4400. carla_stderr("CarlaPluginLV2::updateLV2State() - error, bad type");
  4401. break;
  4402. case LV2_STATE_ERR_BAD_FLAGS:
  4403. carla_stderr("CarlaPluginLV2::updateLV2State() - error, bad flags");
  4404. break;
  4405. case LV2_STATE_ERR_NO_FEATURE:
  4406. carla_stderr("CarlaPluginLV2::updateLV2State() - error, missing feature");
  4407. break;
  4408. case LV2_STATE_ERR_NO_PROPERTY:
  4409. carla_stderr("CarlaPluginLV2::updateLV2State() - error, missing property");
  4410. break;
  4411. case LV2_STATE_ERR_NO_SPACE:
  4412. carla_stderr("CarlaPluginLV2::updateLV2State() - error, insufficient space");
  4413. break;
  4414. }
  4415. }
  4416. // -------------------------------------------------------------------
  4417. bool isRealtimeSafe() const noexcept
  4418. {
  4419. CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
  4420. for (uint32_t i=0; i < fRdfDescriptor->FeatureCount; ++i)
  4421. {
  4422. if (std::strcmp(fRdfDescriptor->Features[i].URI, LV2_CORE__hardRTCapable) == 0)
  4423. return true;
  4424. }
  4425. return false;
  4426. }
  4427. // -------------------------------------------------------------------
  4428. bool isUiBridgeable(const uint32_t uiId) const noexcept
  4429. {
  4430. CARLA_SAFE_ASSERT_RETURN(uiId < fRdfDescriptor->UICount, false);
  4431. #ifndef LV2_UIS_ONLY_INPROCESS
  4432. const LV2_RDF_UI* const rdfUI(&fRdfDescriptor->UIs[uiId]);
  4433. for (uint32_t i=0; i < rdfUI->FeatureCount; ++i)
  4434. {
  4435. const LV2_RDF_Feature& feat(rdfUI->Features[i]);
  4436. if (! feat.Required)
  4437. continue;
  4438. if (std::strcmp(feat.URI, LV2_INSTANCE_ACCESS_URI) == 0)
  4439. return false;
  4440. if (std::strcmp(feat.URI, LV2_DATA_ACCESS_URI) == 0)
  4441. return false;
  4442. }
  4443. // Calf UIs are mostly useless without their special graphs
  4444. // but they can be crashy under certain conditions, so follow user preferences
  4445. if (std::strstr(rdfUI->URI, "http://calf.sourceforge.net/plugins/gui/") != nullptr)
  4446. return pData->engine->getOptions().preferUiBridges;
  4447. // LSP-Plugins UIs make heavy use of URIDs, for which carla right now is very slow
  4448. // FIXME after some optimization, remove this
  4449. if (std::strstr(rdfUI->URI, "http://lsp-plug.in/ui/lv2/") != nullptr)
  4450. return false;
  4451. return true;
  4452. #else
  4453. return false;
  4454. #endif
  4455. }
  4456. bool isUiResizable() const noexcept
  4457. {
  4458. CARLA_SAFE_ASSERT_RETURN(fUI.rdfDescriptor != nullptr, false);
  4459. for (uint32_t i=0; i < fUI.rdfDescriptor->FeatureCount; ++i)
  4460. {
  4461. if (std::strcmp(fUI.rdfDescriptor->Features[i].URI, LV2_UI__fixedSize) == 0)
  4462. return false;
  4463. if (std::strcmp(fUI.rdfDescriptor->Features[i].URI, LV2_UI__noUserResize) == 0)
  4464. return false;
  4465. }
  4466. return true;
  4467. }
  4468. const char* getUiBridgeBinary(const LV2_Property type) const
  4469. {
  4470. CarlaString bridgeBinary(pData->engine->getOptions().binaryDir);
  4471. if (bridgeBinary.isEmpty())
  4472. return nullptr;
  4473. switch (type)
  4474. {
  4475. case LV2_UI_GTK2:
  4476. bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-gtk2";
  4477. break;
  4478. case LV2_UI_GTK3:
  4479. bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-gtk3";
  4480. break;
  4481. case LV2_UI_QT4:
  4482. bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-qt4";
  4483. break;
  4484. case LV2_UI_QT5:
  4485. bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-qt5";
  4486. break;
  4487. case LV2_UI_COCOA:
  4488. bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-cocoa";
  4489. break;
  4490. case LV2_UI_WINDOWS:
  4491. bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-windows";
  4492. break;
  4493. case LV2_UI_X11:
  4494. bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-x11";
  4495. break;
  4496. case LV2_UI_MOD:
  4497. bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-modgui";
  4498. break;
  4499. #if 0
  4500. case LV2_UI_EXTERNAL:
  4501. case LV2_UI_OLD_EXTERNAL:
  4502. bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-external";
  4503. break;
  4504. #endif
  4505. default:
  4506. return nullptr;
  4507. }
  4508. #ifdef CARLA_OS_WIN
  4509. bridgeBinary += ".exe";
  4510. #endif
  4511. if (! File(bridgeBinary.buffer()).existsAsFile())
  4512. return nullptr;
  4513. return bridgeBinary.dupSafe();
  4514. }
  4515. // -------------------------------------------------------------------
  4516. void recheckExtensions()
  4517. {
  4518. CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr,);
  4519. carla_debug("CarlaPluginLV2::recheckExtensions()");
  4520. fExt.options = nullptr;
  4521. fExt.programs = nullptr;
  4522. fExt.state = nullptr;
  4523. fExt.worker = nullptr;
  4524. fExt.inlineDisplay = nullptr;
  4525. for (uint32_t i=0; i < fRdfDescriptor->ExtensionCount; ++i)
  4526. {
  4527. const char* const extension = fRdfDescriptor->Extensions[i];
  4528. CARLA_SAFE_ASSERT_CONTINUE(extension != nullptr);
  4529. /**/ if (std::strcmp(extension, LV2_OPTIONS__interface) == 0)
  4530. pData->hints |= PLUGIN_HAS_EXTENSION_OPTIONS;
  4531. else if (std::strcmp(extension, LV2_PROGRAMS__Interface) == 0)
  4532. pData->hints |= PLUGIN_HAS_EXTENSION_PROGRAMS;
  4533. else if (std::strcmp(extension, LV2_STATE__interface) == 0)
  4534. pData->hints |= PLUGIN_HAS_EXTENSION_STATE;
  4535. else if (std::strcmp(extension, LV2_WORKER__interface) == 0)
  4536. pData->hints |= PLUGIN_HAS_EXTENSION_WORKER;
  4537. else if (std::strcmp(extension, LV2_INLINEDISPLAY__interface) == 0)
  4538. pData->hints |= PLUGIN_HAS_EXTENSION_INLINE_DISPLAY;
  4539. else if (std::strcmp(extension, LV2_MIDNAM__interface) == 0)
  4540. pData->hints |= PLUGIN_HAS_EXTENSION_MIDNAM;
  4541. else
  4542. carla_stdout("Plugin '%s' has non-supported extension: '%s'", fRdfDescriptor->URI, extension);
  4543. }
  4544. // Fix for broken plugins, nasty!
  4545. for (uint32_t i=0; i < fRdfDescriptor->FeatureCount; ++i)
  4546. {
  4547. const LV2_RDF_Feature& feature(fRdfDescriptor->Features[i]);
  4548. if (std::strcmp(feature.URI, LV2_INLINEDISPLAY__queue_draw) == 0)
  4549. {
  4550. if (pData->hints & PLUGIN_HAS_EXTENSION_INLINE_DISPLAY)
  4551. break;
  4552. carla_stdout("Plugin '%s' uses inline-display but does not set extension data, nasty!", fRdfDescriptor->URI);
  4553. pData->hints |= PLUGIN_HAS_EXTENSION_INLINE_DISPLAY;
  4554. }
  4555. else if (std::strcmp(feature.URI, LV2_MIDNAM__update) == 0)
  4556. {
  4557. if (pData->hints & PLUGIN_HAS_EXTENSION_MIDNAM)
  4558. break;
  4559. carla_stdout("Plugin '%s' uses midnam but does not set extension data, nasty!", fRdfDescriptor->URI);
  4560. pData->hints |= PLUGIN_HAS_EXTENSION_MIDNAM;
  4561. }
  4562. }
  4563. if (fDescriptor->extension_data != nullptr)
  4564. {
  4565. if (pData->hints & PLUGIN_HAS_EXTENSION_OPTIONS)
  4566. fExt.options = (const LV2_Options_Interface*)fDescriptor->extension_data(LV2_OPTIONS__interface);
  4567. if (pData->hints & PLUGIN_HAS_EXTENSION_PROGRAMS)
  4568. fExt.programs = (const LV2_Programs_Interface*)fDescriptor->extension_data(LV2_PROGRAMS__Interface);
  4569. if (pData->hints & PLUGIN_HAS_EXTENSION_STATE)
  4570. fExt.state = (const LV2_State_Interface*)fDescriptor->extension_data(LV2_STATE__interface);
  4571. if (pData->hints & PLUGIN_HAS_EXTENSION_WORKER)
  4572. fExt.worker = (const LV2_Worker_Interface*)fDescriptor->extension_data(LV2_WORKER__interface);
  4573. if (pData->hints & PLUGIN_HAS_EXTENSION_INLINE_DISPLAY)
  4574. fExt.inlineDisplay = (const LV2_Inline_Display_Interface*)fDescriptor->extension_data(LV2_INLINEDISPLAY__interface);
  4575. if (pData->hints & PLUGIN_HAS_EXTENSION_MIDNAM)
  4576. fExt.midnam = (const LV2_Midnam_Interface*)fDescriptor->extension_data(LV2_MIDNAM__interface);
  4577. // check if invalid
  4578. if (fExt.options != nullptr && fExt.options->get == nullptr && fExt.options->set == nullptr)
  4579. fExt.options = nullptr;
  4580. if (fExt.programs != nullptr && (fExt.programs->get_program == nullptr || fExt.programs->select_program == nullptr))
  4581. fExt.programs = nullptr;
  4582. if (fExt.state != nullptr && (fExt.state->save == nullptr || fExt.state->restore == nullptr))
  4583. fExt.state = nullptr;
  4584. if (fExt.worker != nullptr && fExt.worker->work == nullptr)
  4585. fExt.worker = nullptr;
  4586. if (fExt.inlineDisplay != nullptr)
  4587. {
  4588. if (fExt.inlineDisplay->render != nullptr)
  4589. {
  4590. pData->hints |= PLUGIN_HAS_INLINE_DISPLAY;
  4591. pData->setCanDeleteLib(false);
  4592. }
  4593. else
  4594. {
  4595. fExt.inlineDisplay = nullptr;
  4596. }
  4597. }
  4598. if (fExt.midnam != nullptr && fExt.midnam->midnam == nullptr)
  4599. fExt.midnam = nullptr;
  4600. }
  4601. CARLA_SAFE_ASSERT_RETURN(fLatencyIndex == -1,);
  4602. int32_t iCtrl=0;
  4603. for (uint32_t i=0, count=fRdfDescriptor->PortCount; i<count; ++i)
  4604. {
  4605. const LV2_Property portTypes(fRdfDescriptor->Ports[i].Types);
  4606. if (! LV2_IS_PORT_CONTROL(portTypes))
  4607. continue;
  4608. const CarlaScopedValueSetter<int32_t> svs(iCtrl, iCtrl, iCtrl+1);
  4609. if (! LV2_IS_PORT_OUTPUT(portTypes))
  4610. continue;
  4611. const LV2_Property portDesignation(fRdfDescriptor->Ports[i].Designation);
  4612. if (! LV2_IS_PORT_DESIGNATION_LATENCY(portDesignation))
  4613. continue;
  4614. fLatencyIndex = iCtrl;
  4615. break;
  4616. }
  4617. }
  4618. // -------------------------------------------------------------------
  4619. void updateUi()
  4620. {
  4621. CARLA_SAFE_ASSERT_RETURN(fUI.handle != nullptr,);
  4622. CARLA_SAFE_ASSERT_RETURN(fUI.descriptor != nullptr,);
  4623. carla_debug("CarlaPluginLV2::updateUi()");
  4624. // update midi program
  4625. if (fExt.uiprograms != nullptr && pData->midiprog.count > 0 && pData->midiprog.current >= 0)
  4626. {
  4627. const MidiProgramData& curData(pData->midiprog.getCurrent());
  4628. fExt.uiprograms->select_program(fUI.handle, curData.bank, curData.program);
  4629. }
  4630. // update control ports
  4631. if (fUI.descriptor->port_event != nullptr)
  4632. {
  4633. float value;
  4634. for (uint32_t i=0; i < pData->param.count; ++i)
  4635. {
  4636. value = getParameterValue(i);
  4637. fUI.descriptor->port_event(fUI.handle, static_cast<uint32_t>(pData->param.data[i].rindex), sizeof(float), kUridNull, &value);
  4638. }
  4639. }
  4640. }
  4641. void inspectAtomForParameterChange(const LV2_Atom* const atom)
  4642. {
  4643. if (atom->type != kUridAtomBlank && atom->type != kUridAtomObject)
  4644. return;
  4645. const LV2_Atom_Object_Body* const objbody = (const LV2_Atom_Object_Body*)(atom + 1);
  4646. if (objbody->otype != kUridPatchSet)
  4647. return;
  4648. const LV2_Atom_URID *property = NULL;
  4649. const LV2_Atom_Bool *carlaParam = NULL;
  4650. const LV2_Atom *value = NULL;
  4651. lv2_atom_object_body_get(atom->size, objbody,
  4652. kUridCarlaParameterChange, (const LV2_Atom**)&carlaParam,
  4653. kUridPatchProperty, (const LV2_Atom**)&property,
  4654. kUridPatchValue, &value,
  4655. 0);
  4656. if (carlaParam != nullptr && carlaParam->body != 0)
  4657. return;
  4658. if (property == nullptr || value == nullptr)
  4659. return;
  4660. switch (value->type)
  4661. {
  4662. case kUridAtomBool:
  4663. case kUridAtomInt:
  4664. //case kUridAtomLong:
  4665. case kUridAtomFloat:
  4666. case kUridAtomDouble:
  4667. break;
  4668. default:
  4669. return;
  4670. }
  4671. uint32_t parameterId;
  4672. if (! getParameterIndexForURID(property->body, parameterId))
  4673. return;
  4674. const uint8_t* const vbody = (const uint8_t*)(value + 1);
  4675. float rvalue;
  4676. switch (value->type)
  4677. {
  4678. case kUridAtomBool:
  4679. rvalue = *(const int32_t*)vbody != 0 ? 1.0f : 0.0f;
  4680. break;
  4681. case kUridAtomInt:
  4682. rvalue = static_cast<float>(*(const int32_t*)vbody);
  4683. break;
  4684. /*
  4685. case kUridAtomLong:
  4686. rvalue = *(int64_t*)vbody;
  4687. break;
  4688. */
  4689. case kUridAtomFloat:
  4690. rvalue = *(const float*)vbody;
  4691. break;
  4692. case kUridAtomDouble:
  4693. rvalue = static_cast<float>(*(const double*)vbody);
  4694. break;
  4695. default:
  4696. rvalue = 0.0f;
  4697. break;
  4698. }
  4699. rvalue = pData->param.getFixedValue(parameterId, rvalue);
  4700. fParamBuffers[parameterId] = rvalue;
  4701. CarlaPlugin::setParameterValue(parameterId, rvalue, false, true, true);
  4702. }
  4703. bool getParameterIndexForURI(const char* const uri, uint32_t& parameterId) noexcept
  4704. {
  4705. parameterId = UINT32_MAX;
  4706. for (uint32_t i=0; i < fRdfDescriptor->ParameterCount; ++i)
  4707. {
  4708. const LV2_RDF_Parameter& rdfParam(fRdfDescriptor->Parameters[i]);
  4709. switch (rdfParam.Type)
  4710. {
  4711. case LV2_PARAMETER_TYPE_BOOL:
  4712. case LV2_PARAMETER_TYPE_INT:
  4713. // case LV2_PARAMETER_TYPE_LONG:
  4714. case LV2_PARAMETER_TYPE_FLOAT:
  4715. case LV2_PARAMETER_TYPE_DOUBLE:
  4716. break;
  4717. default:
  4718. continue;
  4719. }
  4720. if (std::strcmp(rdfParam.URI, uri) == 0)
  4721. {
  4722. const int32_t rindex = static_cast<int32_t>(fRdfDescriptor->PortCount + i);
  4723. for (uint32_t j=0; j < pData->param.count; ++j)
  4724. {
  4725. if (pData->param.data[j].rindex == rindex)
  4726. {
  4727. parameterId = j;
  4728. break;
  4729. }
  4730. }
  4731. break;
  4732. }
  4733. }
  4734. return (parameterId != UINT32_MAX);
  4735. }
  4736. bool getParameterIndexForURID(const LV2_URID urid, uint32_t& parameterId) noexcept
  4737. {
  4738. parameterId = UINT32_MAX;
  4739. if (urid >= fCustomURIDs.size())
  4740. return false;
  4741. for (uint32_t i=0; i < fRdfDescriptor->ParameterCount; ++i)
  4742. {
  4743. const LV2_RDF_Parameter& rdfParam(fRdfDescriptor->Parameters[i]);
  4744. switch (rdfParam.Type)
  4745. {
  4746. case LV2_PARAMETER_TYPE_BOOL:
  4747. case LV2_PARAMETER_TYPE_INT:
  4748. // case LV2_PARAMETER_TYPE_LONG:
  4749. case LV2_PARAMETER_TYPE_FLOAT:
  4750. case LV2_PARAMETER_TYPE_DOUBLE:
  4751. break;
  4752. default:
  4753. continue;
  4754. }
  4755. const std::string& uri(fCustomURIDs[urid]);
  4756. if (uri != rdfParam.URI)
  4757. continue;
  4758. const int32_t rindex = static_cast<int32_t>(fRdfDescriptor->PortCount + i);
  4759. for (uint32_t j=0; j < pData->param.count; ++j)
  4760. {
  4761. if (pData->param.data[j].rindex == rindex)
  4762. {
  4763. parameterId = j;
  4764. break;
  4765. }
  4766. }
  4767. break;
  4768. }
  4769. return (parameterId != UINT32_MAX);
  4770. }
  4771. // -------------------------------------------------------------------
  4772. LV2_URID getCustomURID(const char* const uri)
  4773. {
  4774. CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0', kUridNull);
  4775. carla_debug("CarlaPluginLV2::getCustomURID(\"%s\")", uri);
  4776. const std::string s_uri(uri);
  4777. const std::ptrdiff_t s_pos(std::find(fCustomURIDs.begin(), fCustomURIDs.end(), s_uri) - fCustomURIDs.begin());
  4778. if (s_pos <= 0 || s_pos >= INT32_MAX)
  4779. return kUridNull;
  4780. const LV2_URID urid = static_cast<LV2_URID>(s_pos);
  4781. const LV2_URID uriCount = static_cast<LV2_URID>(fCustomURIDs.size());
  4782. if (urid < uriCount)
  4783. return urid;
  4784. CARLA_SAFE_ASSERT(urid == uriCount);
  4785. fCustomURIDs.push_back(uri);
  4786. #ifndef LV2_UIS_ONLY_INPROCESS
  4787. if (fUI.type == UI::TYPE_BRIDGE && fPipeServer.isPipeRunning())
  4788. fPipeServer.writeLv2UridMessage(urid, uri);
  4789. #endif
  4790. return urid;
  4791. }
  4792. const char* getCustomURIDString(const LV2_URID urid) const noexcept
  4793. {
  4794. CARLA_SAFE_ASSERT_RETURN(urid != kUridNull, kUnmapFallback);
  4795. CARLA_SAFE_ASSERT_RETURN(urid < fCustomURIDs.size(), kUnmapFallback);
  4796. carla_debug("CarlaPluginLV2::getCustomURIString(%i)", urid);
  4797. return fCustomURIDs[urid].c_str();
  4798. }
  4799. // -------------------------------------------------------------------
  4800. void handleProgramChanged(const int32_t index)
  4801. {
  4802. CARLA_SAFE_ASSERT_RETURN(index >= -1,);
  4803. carla_debug("CarlaPluginLV2::handleProgramChanged(%i)", index);
  4804. if (index == -1)
  4805. {
  4806. const ScopedSingleProcessLocker spl(this, true);
  4807. return reloadPrograms(false);
  4808. }
  4809. if (index < static_cast<int32_t>(pData->midiprog.count) && fExt.programs != nullptr && fExt.programs->get_program != nullptr)
  4810. {
  4811. if (const LV2_Program_Descriptor* const progDesc = fExt.programs->get_program(fHandle, static_cast<uint32_t>(index)))
  4812. {
  4813. CARLA_SAFE_ASSERT_RETURN(progDesc->name != nullptr,);
  4814. if (pData->midiprog.data[index].name != nullptr)
  4815. delete[] pData->midiprog.data[index].name;
  4816. pData->midiprog.data[index].name = carla_strdup(progDesc->name);
  4817. if (index == pData->midiprog.current)
  4818. pData->engine->callback(true, true, ENGINE_CALLBACK_UPDATE, pData->id, 0, 0, 0, 0.0, nullptr);
  4819. else
  4820. pData->engine->callback(true, true, ENGINE_CALLBACK_RELOAD_PROGRAMS, pData->id, 0, 0, 0, 0.0, nullptr);
  4821. }
  4822. }
  4823. }
  4824. // -------------------------------------------------------------------
  4825. LV2_Resize_Port_Status handleResizePort(const uint32_t index, const size_t size)
  4826. {
  4827. CARLA_SAFE_ASSERT_RETURN(size > 0, LV2_RESIZE_PORT_ERR_UNKNOWN);
  4828. carla_debug("CarlaPluginLV2::handleResizePort(%i, " P_SIZE ")", index, size);
  4829. // TODO
  4830. return LV2_RESIZE_PORT_ERR_NO_SPACE;
  4831. (void)index;
  4832. }
  4833. // -------------------------------------------------------------------
  4834. char* handleStateMapToAbstractPath(const bool temporary, const char* const absolutePath) const
  4835. {
  4836. // may already be an abstract path
  4837. if (! File::isAbsolutePath(absolutePath))
  4838. return strdup(absolutePath);
  4839. File projectDir, targetDir;
  4840. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  4841. if (const char* const projFolder = pData->engine->getCurrentProjectFolder())
  4842. projectDir = projFolder;
  4843. else
  4844. #endif
  4845. projectDir = File::getCurrentWorkingDirectory();
  4846. if (projectDir.isNull())
  4847. {
  4848. carla_stdout("Project directory not set, cannot map absolutePath %s", absolutePath);
  4849. return nullptr;
  4850. }
  4851. water::String basedir(pData->engine->getName());
  4852. if (temporary)
  4853. basedir += ".tmp";
  4854. targetDir = projectDir.getChildFile(basedir)
  4855. .getChildFile(getName());
  4856. if (! targetDir.exists())
  4857. targetDir.createDirectory();
  4858. const File wabsolutePath(absolutePath);
  4859. // we may be saving to non-tmp path, let's check
  4860. if (! temporary)
  4861. {
  4862. const File tmpDir = projectDir.getChildFile(basedir + ".tmp")
  4863. .getChildFile(getName());
  4864. if (wabsolutePath.getFullPathName().startsWith(tmpDir.getFullPathName()))
  4865. {
  4866. // gotcha, the temporary path is now the real one
  4867. targetDir = tmpDir;
  4868. }
  4869. else if (! wabsolutePath.getFullPathName().startsWith(targetDir.getFullPathName()))
  4870. {
  4871. // seems like a normal save, let's be nice and put a symlink
  4872. const water::String abstractFilename(wabsolutePath.getFileName());
  4873. const File targetPath(targetDir.getChildFile(abstractFilename));
  4874. wabsolutePath.createSymbolicLink(targetPath, true);
  4875. carla_stdout("Creating symlink for '%s' in '%s'", absolutePath, targetDir.getFullPathName().toRawUTF8());
  4876. return strdup(abstractFilename.toRawUTF8());
  4877. }
  4878. }
  4879. carla_stdout("Mapping absolutePath '%s' relative to targetDir '%s'",
  4880. absolutePath, targetDir.getFullPathName().toRawUTF8());
  4881. return strdup(wabsolutePath.getRelativePathFrom(targetDir).toRawUTF8());
  4882. }
  4883. File handleStateMapToAbsolutePath(const bool createDirIfNeeded,
  4884. const bool symlinkIfNeeded,
  4885. const bool temporary,
  4886. const char* const abstractPath) const
  4887. {
  4888. File targetDir, targetPath;
  4889. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  4890. if (const char* const projFolder = pData->engine->getCurrentProjectFolder())
  4891. targetDir = projFolder;
  4892. else
  4893. #endif
  4894. targetDir = File::getCurrentWorkingDirectory();
  4895. if (targetDir.isNull())
  4896. {
  4897. carla_stdout("Project directory not set, cannot map abstractPath '%s'", abstractPath);
  4898. return File();
  4899. }
  4900. water::String basedir(pData->engine->getName());
  4901. if (temporary)
  4902. basedir += ".tmp";
  4903. targetDir = targetDir.getChildFile(basedir)
  4904. .getChildFile(getName());
  4905. if (createDirIfNeeded && ! targetDir.exists())
  4906. targetDir.createDirectory();
  4907. if (File::isAbsolutePath(abstractPath))
  4908. {
  4909. File wabstractPath(abstractPath);
  4910. targetPath = targetDir.getChildFile(wabstractPath.getFileName());
  4911. if (symlinkIfNeeded)
  4912. {
  4913. carla_stdout("Creating symlink for '%s' in '%s'",
  4914. abstractPath, targetDir.getFullPathName().toRawUTF8());
  4915. wabstractPath.createSymbolicLink(targetPath, true);
  4916. }
  4917. }
  4918. else
  4919. {
  4920. targetPath = targetDir.getChildFile(abstractPath);
  4921. targetDir = targetPath.getParentDirectory();
  4922. if (createDirIfNeeded && ! targetDir.exists())
  4923. targetDir.createDirectory();
  4924. }
  4925. if (std::strcmp(abstractPath, ".") != 0)
  4926. carla_stdout("Mapping abstractPath '%s' relative to targetDir '%s'",
  4927. abstractPath, targetDir.getFullPathName().toRawUTF8());
  4928. return targetPath;
  4929. }
  4930. LV2_State_Status handleStateStore(const uint32_t key, const void* const value, const size_t size, const uint32_t type, const uint32_t flags)
  4931. {
  4932. CARLA_SAFE_ASSERT_RETURN(key != kUridNull, LV2_STATE_ERR_NO_PROPERTY);
  4933. CARLA_SAFE_ASSERT_RETURN(value != nullptr, LV2_STATE_ERR_NO_PROPERTY);
  4934. CARLA_SAFE_ASSERT_RETURN(size > 0, LV2_STATE_ERR_NO_PROPERTY);
  4935. CARLA_SAFE_ASSERT_RETURN(type != kUridNull, LV2_STATE_ERR_BAD_TYPE);
  4936. // FIXME linuxsampler does not set POD flag
  4937. // CARLA_SAFE_ASSERT_RETURN(flags & LV2_STATE_IS_POD, LV2_STATE_ERR_BAD_FLAGS);
  4938. carla_debug("CarlaPluginLV2::handleStateStore(%i:\"%s\", %p, " P_SIZE ", %i:\"%s\", %i)",
  4939. key, carla_lv2_urid_unmap(this, key), value, size, type, carla_lv2_urid_unmap(this, type), flags);
  4940. const char* const skey(carla_lv2_urid_unmap(this, key));
  4941. const char* const stype(carla_lv2_urid_unmap(this, type));
  4942. CARLA_SAFE_ASSERT_RETURN(skey != nullptr && skey != kUnmapFallback, LV2_STATE_ERR_BAD_TYPE);
  4943. CARLA_SAFE_ASSERT_RETURN(stype != nullptr && stype != kUnmapFallback, LV2_STATE_ERR_BAD_TYPE);
  4944. // Check if we already have this key
  4945. for (LinkedList<CustomData>::Itenerator it = pData->custom.begin2(); it.valid(); it.next())
  4946. {
  4947. CustomData& cData(it.getValue(kCustomDataFallbackNC));
  4948. CARLA_SAFE_ASSERT_CONTINUE(cData.isValid());
  4949. if (std::strcmp(cData.key, skey) == 0)
  4950. {
  4951. // found it
  4952. delete[] cData.value;
  4953. if (type == kUridAtomString || type == kUridAtomPath)
  4954. cData.value = carla_strdup((const char*)value);
  4955. else
  4956. cData.value = CarlaString::asBase64(value, size).dup();
  4957. return LV2_STATE_SUCCESS;
  4958. }
  4959. }
  4960. // Otherwise store it
  4961. CustomData newData;
  4962. newData.type = carla_strdup(stype);
  4963. newData.key = carla_strdup(skey);
  4964. if (type == kUridAtomString || type == kUridAtomPath)
  4965. newData.value = carla_strdup((const char*)value);
  4966. else
  4967. newData.value = CarlaString::asBase64(value, size).dup();
  4968. pData->custom.append(newData);
  4969. return LV2_STATE_SUCCESS;
  4970. // unused
  4971. (void)flags;
  4972. }
  4973. const void* handleStateRetrieve(const uint32_t key, size_t* const size, uint32_t* const type, uint32_t* const flags)
  4974. {
  4975. CARLA_SAFE_ASSERT_RETURN(key != kUridNull, nullptr);
  4976. CARLA_SAFE_ASSERT_RETURN(size != nullptr, nullptr);
  4977. CARLA_SAFE_ASSERT_RETURN(type != nullptr, nullptr);
  4978. CARLA_SAFE_ASSERT_RETURN(flags != nullptr, nullptr);
  4979. carla_debug("CarlaPluginLV2::handleStateRetrieve(%i, %p, %p, %p)", key, size, type, flags);
  4980. const char* const skey(carla_lv2_urid_unmap(this, key));
  4981. CARLA_SAFE_ASSERT_RETURN(skey != nullptr && skey != kUnmapFallback, nullptr);
  4982. const char* stype = nullptr;
  4983. const char* stringData = nullptr;
  4984. for (LinkedList<CustomData>::Itenerator it = pData->custom.begin2(); it.valid(); it.next())
  4985. {
  4986. const CustomData& cData(it.getValue(kCustomDataFallback));
  4987. CARLA_SAFE_ASSERT_CONTINUE(cData.isValid());
  4988. if (std::strcmp(cData.key, skey) == 0)
  4989. {
  4990. stype = cData.type;
  4991. stringData = cData.value;
  4992. break;
  4993. }
  4994. }
  4995. if (stype == nullptr || stringData == nullptr)
  4996. {
  4997. carla_stderr("Plugin requested value for '%s' which is not available", skey);
  4998. *size = *type = *flags = 0;
  4999. return nullptr;
  5000. }
  5001. *type = carla_lv2_urid_map(this, stype);
  5002. *flags = LV2_STATE_IS_POD;
  5003. if (*type == kUridAtomString || *type == kUridAtomPath)
  5004. {
  5005. *size = std::strlen(stringData);
  5006. return stringData;
  5007. }
  5008. if (fLastStateChunk != nullptr)
  5009. {
  5010. std::free(fLastStateChunk);
  5011. fLastStateChunk = nullptr;
  5012. }
  5013. std::vector<uint8_t> chunk(carla_getChunkFromBase64String(stringData));
  5014. CARLA_SAFE_ASSERT_RETURN(chunk.size() > 0, nullptr);
  5015. fLastStateChunk = std::malloc(chunk.size());
  5016. CARLA_SAFE_ASSERT_RETURN(fLastStateChunk != nullptr, nullptr);
  5017. #ifdef CARLA_PROPER_CPP11_SUPPORT
  5018. std::memcpy(fLastStateChunk, chunk.data(), chunk.size());
  5019. #else
  5020. std::memcpy(fLastStateChunk, &chunk.front(), chunk.size());
  5021. #endif
  5022. *size = chunk.size();
  5023. return fLastStateChunk;
  5024. }
  5025. // -------------------------------------------------------------------
  5026. LV2_Worker_Status handleWorkerSchedule(const uint32_t size, const void* const data)
  5027. {
  5028. CARLA_SAFE_ASSERT_RETURN(fExt.worker != nullptr && fExt.worker->work != nullptr, LV2_WORKER_ERR_UNKNOWN);
  5029. CARLA_SAFE_ASSERT_RETURN(fEventsIn.ctrl != nullptr, LV2_WORKER_ERR_UNKNOWN);
  5030. carla_debug("CarlaPluginLV2::handleWorkerSchedule(%i, %p)", size, data);
  5031. if (pData->engine->isOffline())
  5032. {
  5033. fExt.worker->work(fHandle, carla_lv2_worker_respond, this, size, data);
  5034. return LV2_WORKER_SUCCESS;
  5035. }
  5036. LV2_Atom atom;
  5037. atom.size = size;
  5038. atom.type = kUridCarlaAtomWorkerIn;
  5039. return fAtomBufferWorkerIn.putChunk(&atom, data, fEventsOut.ctrlIndex) ? LV2_WORKER_SUCCESS : LV2_WORKER_ERR_NO_SPACE;
  5040. }
  5041. LV2_Worker_Status handleWorkerRespond(const uint32_t size, const void* const data)
  5042. {
  5043. CARLA_SAFE_ASSERT_RETURN(fExt.worker != nullptr && fExt.worker->work_response != nullptr, LV2_WORKER_ERR_UNKNOWN);
  5044. carla_debug("CarlaPluginLV2::handleWorkerRespond(%i, %p)", size, data);
  5045. LV2_Atom atom;
  5046. atom.size = size;
  5047. atom.type = kUridCarlaAtomWorkerResp;
  5048. return fAtomBufferWorkerResp.putChunk(&atom, data, fEventsIn.ctrlIndex) ? LV2_WORKER_SUCCESS : LV2_WORKER_ERR_NO_SPACE;
  5049. }
  5050. // -------------------------------------------------------------------
  5051. void handleInlineDisplayQueueRedraw()
  5052. {
  5053. switch (pData->engine->getProccessMode())
  5054. {
  5055. case ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS:
  5056. case ENGINE_PROCESS_MODE_PATCHBAY:
  5057. fInlineDisplayNeedsRedraw = true;
  5058. break;
  5059. default:
  5060. break;
  5061. }
  5062. }
  5063. const LV2_Inline_Display_Image_Surface* renderInlineDisplay(const uint32_t width, const uint32_t height) const
  5064. {
  5065. CARLA_SAFE_ASSERT_RETURN(fExt.inlineDisplay != nullptr && fExt.inlineDisplay->render != nullptr, nullptr);
  5066. CARLA_SAFE_ASSERT_RETURN(width > 0, nullptr);
  5067. CARLA_SAFE_ASSERT_RETURN(height > 0, nullptr);
  5068. return fExt.inlineDisplay->render(fHandle, width, height);
  5069. }
  5070. // -------------------------------------------------------------------
  5071. void handleMidnamUpdate()
  5072. {
  5073. CARLA_SAFE_ASSERT_RETURN(fExt.midnam != nullptr,);
  5074. if (fEventsIn.ctrl == nullptr)
  5075. return;
  5076. char* const midnam = fExt.midnam->midnam(fHandle);
  5077. CARLA_SAFE_ASSERT_RETURN(midnam != nullptr,);
  5078. fEventsIn.ctrl->port->setMetaData("http://www.midi.org/dtds/MIDINameDocument10.dtd", midnam, "text/xml");
  5079. if (fExt.midnam->free != nullptr)
  5080. fExt.midnam->free(midnam);
  5081. }
  5082. // -------------------------------------------------------------------
  5083. void handleExternalUIClosed()
  5084. {
  5085. CARLA_SAFE_ASSERT_RETURN(fUI.type == UI::TYPE_EXTERNAL,);
  5086. carla_debug("CarlaPluginLV2::handleExternalUIClosed()");
  5087. fNeedsUiClose = true;
  5088. }
  5089. void handlePluginUIClosed() override
  5090. {
  5091. CARLA_SAFE_ASSERT_RETURN(fUI.type == UI::TYPE_EMBED,);
  5092. CARLA_SAFE_ASSERT_RETURN(fUI.window != nullptr,);
  5093. carla_debug("CarlaPluginLV2::handlePluginUIClosed()");
  5094. fNeedsUiClose = true;
  5095. }
  5096. void handlePluginUIResized(const uint width, const uint height) override
  5097. {
  5098. CARLA_SAFE_ASSERT_RETURN(fUI.type == UI::TYPE_EMBED,);
  5099. CARLA_SAFE_ASSERT_RETURN(fUI.window != nullptr,);
  5100. carla_debug("CarlaPluginLV2::handlePluginUIResized(%u, %u)", width, height);
  5101. if (fUI.handle != nullptr && fExt.uiresize != nullptr)
  5102. fExt.uiresize->ui_resize(fUI.handle, static_cast<int>(width), static_cast<int>(height));
  5103. }
  5104. // -------------------------------------------------------------------
  5105. uint32_t handleUIPortMap(const char* const symbol) const noexcept
  5106. {
  5107. CARLA_SAFE_ASSERT_RETURN(symbol != nullptr && symbol[0] != '\0', LV2UI_INVALID_PORT_INDEX);
  5108. carla_debug("CarlaPluginLV2::handleUIPortMap(\"%s\")", symbol);
  5109. for (uint32_t i=0; i < fRdfDescriptor->PortCount; ++i)
  5110. {
  5111. if (std::strcmp(fRdfDescriptor->Ports[i].Symbol, symbol) == 0)
  5112. return i;
  5113. }
  5114. return LV2UI_INVALID_PORT_INDEX;
  5115. }
  5116. LV2UI_Request_Value_Status handleUIRequestValue(const LV2_URID key,
  5117. const LV2_URID type,
  5118. const LV2_Feature* const* features)
  5119. {
  5120. CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL, LV2UI_REQUEST_VALUE_ERR_UNKNOWN);
  5121. carla_debug("CarlaPluginLV2::handleUIRequestValue(%u, %u, %p)", key, type, features);
  5122. if (type != kUridAtomPath)
  5123. return LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED;
  5124. const char* const uri = getCustomURIDString(key);
  5125. CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri != kUnmapFallback, LV2UI_REQUEST_VALUE_ERR_UNKNOWN);
  5126. // check if a file browser is already open
  5127. if (fUI.fileNeededForURI != nullptr || fUI.fileBrowserOpen)
  5128. return LV2UI_REQUEST_VALUE_BUSY;
  5129. for (uint32_t i=0; i < fRdfDescriptor->ParameterCount; ++i)
  5130. {
  5131. if (fRdfDescriptor->Parameters[i].Type != LV2_PARAMETER_TYPE_PATH)
  5132. continue;
  5133. if (std::strcmp(fRdfDescriptor->Parameters[i].URI, uri) != 0)
  5134. continue;
  5135. // TODO file browser filters, also store label to use for title
  5136. fUI.fileNeededForURI = uri;
  5137. return LV2UI_REQUEST_VALUE_SUCCESS;
  5138. }
  5139. return LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED;
  5140. // may be unused
  5141. (void)features;
  5142. }
  5143. int handleUIResize(const int width, const int height)
  5144. {
  5145. CARLA_SAFE_ASSERT_RETURN(width > 0, 1);
  5146. CARLA_SAFE_ASSERT_RETURN(height > 0, 1);
  5147. carla_debug("CarlaPluginLV2::handleUIResize(%i, %i)", width, height);
  5148. if (fUI.embedded)
  5149. {
  5150. pData->engine->callback(true, true,
  5151. ENGINE_CALLBACK_EMBED_UI_RESIZED,
  5152. pData->id, width, height,
  5153. 0, 0.0f, nullptr);
  5154. }
  5155. else
  5156. {
  5157. CARLA_SAFE_ASSERT_RETURN(fUI.window != nullptr, 1);
  5158. fUI.window->setSize(static_cast<uint>(width), static_cast<uint>(height), true, true);
  5159. }
  5160. return 0;
  5161. }
  5162. void handleUITouch(const uint32_t rindex, const bool touch)
  5163. {
  5164. carla_debug("CarlaPluginLV2::handleUITouch(%u, %s)", rindex, bool2str(touch));
  5165. uint32_t index = LV2UI_INVALID_PORT_INDEX;
  5166. for (uint32_t i=0; i < pData->param.count; ++i)
  5167. {
  5168. if (pData->param.data[i].rindex != static_cast<int32_t>(rindex))
  5169. continue;
  5170. index = i;
  5171. break;
  5172. }
  5173. CARLA_SAFE_ASSERT_RETURN(index != LV2UI_INVALID_PORT_INDEX,);
  5174. pData->engine->touchPluginParameter(pData->id, index, touch);
  5175. }
  5176. void handleUIWrite(const uint32_t rindex, const uint32_t bufferSize, const uint32_t format, const void* const buffer)
  5177. {
  5178. CARLA_SAFE_ASSERT_RETURN(buffer != nullptr,);
  5179. CARLA_SAFE_ASSERT_RETURN(bufferSize > 0,);
  5180. carla_debug("CarlaPluginLV2::handleUIWrite(%i, %i, %i, %p)", rindex, bufferSize, format, buffer);
  5181. uint32_t index = LV2UI_INVALID_PORT_INDEX;
  5182. switch (format)
  5183. {
  5184. case kUridNull: {
  5185. CARLA_SAFE_ASSERT_RETURN(rindex < fRdfDescriptor->PortCount,);
  5186. CARLA_SAFE_ASSERT_RETURN(bufferSize == sizeof(float),);
  5187. for (uint32_t i=0; i < pData->param.count; ++i)
  5188. {
  5189. if (pData->param.data[i].rindex != static_cast<int32_t>(rindex))
  5190. continue;
  5191. index = i;
  5192. break;
  5193. }
  5194. CARLA_SAFE_ASSERT_RETURN(index != LV2UI_INVALID_PORT_INDEX,);
  5195. const float value(*(const float*)buffer);
  5196. // check if we should feedback message back to UI
  5197. bool sendGui = false;
  5198. if (const uint32_t notifCount = fUI.rdfDescriptor->PortNotificationCount)
  5199. {
  5200. const char* const portSymbol = fRdfDescriptor->Ports[rindex].Symbol;
  5201. for (uint32_t i=0; i < notifCount; ++i)
  5202. {
  5203. const LV2_RDF_UI_PortNotification& portNotif(fUI.rdfDescriptor->PortNotifications[i]);
  5204. if (portNotif.Protocol != LV2_UI_PORT_PROTOCOL_FLOAT)
  5205. continue;
  5206. if (portNotif.Symbol != nullptr)
  5207. {
  5208. if (std::strcmp(portNotif.Symbol, portSymbol) != 0)
  5209. continue;
  5210. }
  5211. else if (portNotif.Index != rindex)
  5212. {
  5213. continue;
  5214. }
  5215. sendGui = true;
  5216. break;
  5217. }
  5218. }
  5219. setParameterValue(index, value, sendGui, true, true);
  5220. } break;
  5221. case kUridAtomTransferAtom:
  5222. case kUridAtomTransferEvent: {
  5223. CARLA_SAFE_ASSERT_RETURN(bufferSize >= sizeof(LV2_Atom),);
  5224. const LV2_Atom* const atom((const LV2_Atom*)buffer);
  5225. // plugins sometimes fail on this, not good...
  5226. const uint32_t totalSize = lv2_atom_total_size(atom);
  5227. const uint32_t paddedSize = lv2_atom_pad_size(totalSize);
  5228. if (bufferSize != totalSize && bufferSize != paddedSize)
  5229. carla_stderr2("Warning: LV2 UI sending atom with invalid size %u! size: %u, padded-size: %u",
  5230. bufferSize, totalSize, paddedSize);
  5231. for (uint32_t i=0; i < fEventsIn.count; ++i)
  5232. {
  5233. if (fEventsIn.data[i].rindex != rindex)
  5234. continue;
  5235. index = i;
  5236. break;
  5237. }
  5238. // for bad plugins
  5239. if (index == LV2UI_INVALID_PORT_INDEX)
  5240. {
  5241. CARLA_SAFE_ASSERT(index != LV2UI_INVALID_PORT_INDEX); // FIXME
  5242. index = fEventsIn.ctrlIndex;
  5243. }
  5244. fAtomBufferEvIn.put(atom, index);
  5245. } break;
  5246. default:
  5247. carla_stdout("CarlaPluginLV2::handleUIWrite(%i, %i, %i:\"%s\", %p) - unknown format",
  5248. rindex, bufferSize, format, carla_lv2_urid_unmap(this, format), buffer);
  5249. break;
  5250. }
  5251. }
  5252. void handleUIBridgeParameter(const char* const uri, const float value)
  5253. {
  5254. CARLA_SAFE_ASSERT_RETURN(uri != nullptr,);
  5255. carla_debug("CarlaPluginLV2::handleUIBridgeParameter(%s, %f)", uri, static_cast<double>(value));
  5256. uint32_t parameterId;
  5257. if (getParameterIndexForURI(uri, parameterId))
  5258. setParameterValue(parameterId, value, false, true, true);
  5259. }
  5260. // -------------------------------------------------------------------
  5261. void handleLilvSetPortValue(const char* const portSymbol, const void* const value, const uint32_t size, const uint32_t type)
  5262. {
  5263. CARLA_SAFE_ASSERT_RETURN(portSymbol != nullptr && portSymbol[0] != '\0',);
  5264. CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
  5265. CARLA_SAFE_ASSERT_RETURN(size > 0,);
  5266. CARLA_SAFE_ASSERT_RETURN(type != kUridNull,);
  5267. carla_debug("CarlaPluginLV2::handleLilvSetPortValue(\"%s\", %p, %i, %i)", portSymbol, value, size, type);
  5268. int32_t rindex = -1;
  5269. for (uint32_t i=0; i < fRdfDescriptor->PortCount; ++i)
  5270. {
  5271. if (std::strcmp(fRdfDescriptor->Ports[i].Symbol, portSymbol) == 0)
  5272. {
  5273. rindex = static_cast<int32_t>(i);
  5274. break;
  5275. }
  5276. }
  5277. CARLA_SAFE_ASSERT_RETURN(rindex >= 0,);
  5278. float paramValue;
  5279. switch (type)
  5280. {
  5281. case kUridAtomBool:
  5282. CARLA_SAFE_ASSERT_RETURN(size == sizeof(int32_t),);
  5283. paramValue = *(const int32_t*)value != 0 ? 1.0f : 0.0f;
  5284. break;
  5285. case kUridAtomDouble:
  5286. CARLA_SAFE_ASSERT_RETURN(size == sizeof(double),);
  5287. paramValue = static_cast<float>((*(const double*)value));
  5288. break;
  5289. case kUridAtomFloat:
  5290. CARLA_SAFE_ASSERT_RETURN(size == sizeof(float),);
  5291. paramValue = *(const float*)value;
  5292. break;
  5293. case kUridAtomInt:
  5294. CARLA_SAFE_ASSERT_RETURN(size == sizeof(int32_t),);
  5295. paramValue = static_cast<float>(*(const int32_t*)value);
  5296. break;
  5297. case kUridAtomLong:
  5298. CARLA_SAFE_ASSERT_RETURN(size == sizeof(int64_t),);
  5299. paramValue = static_cast<float>(*(const int64_t*)value);
  5300. break;
  5301. default:
  5302. carla_stdout("CarlaPluginLV2::handleLilvSetPortValue(\"%s\", %p, %i, %i:\"%s\") - unknown type",
  5303. portSymbol, value, size, type, carla_lv2_urid_unmap(this, type));
  5304. return;
  5305. }
  5306. for (uint32_t i=0; i < pData->param.count; ++i)
  5307. {
  5308. if (pData->param.data[i].rindex == rindex)
  5309. {
  5310. setParameterValueRT(i, paramValue, 0, true);
  5311. break;
  5312. }
  5313. }
  5314. }
  5315. // -------------------------------------------------------------------
  5316. void* getNativeHandle() const noexcept override
  5317. {
  5318. return fHandle;
  5319. }
  5320. const void* getNativeDescriptor() const noexcept override
  5321. {
  5322. return fDescriptor;
  5323. }
  5324. #ifndef LV2_UIS_ONLY_INPROCESS
  5325. uintptr_t getUiBridgeProcessId() const noexcept override
  5326. {
  5327. return fPipeServer.isPipeRunning() ? fPipeServer.getPID() : 0;
  5328. }
  5329. #endif
  5330. // -------------------------------------------------------------------
  5331. public:
  5332. bool init(const CarlaPluginPtr plugin,
  5333. const char* const name, const char* const uri, const uint options,
  5334. const char*& needsArchBridge)
  5335. {
  5336. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false);
  5337. // ---------------------------------------------------------------
  5338. // first checks
  5339. if (pData->client != nullptr)
  5340. {
  5341. pData->engine->setLastError("Plugin client is already registered");
  5342. return false;
  5343. }
  5344. if (uri == nullptr || uri[0] == '\0')
  5345. {
  5346. pData->engine->setLastError("null uri");
  5347. return false;
  5348. }
  5349. const EngineOptions& opts(pData->engine->getOptions());
  5350. // ---------------------------------------------------------------
  5351. // Init LV2 World if needed, sets LV2_PATH for lilv
  5352. Lv2WorldClass& lv2World(Lv2WorldClass::getInstance());
  5353. if (opts.pathLV2 != nullptr && opts.pathLV2[0] != '\0')
  5354. lv2World.initIfNeeded(opts.pathLV2);
  5355. else if (const char* const LV2_PATH = std::getenv("LV2_PATH"))
  5356. lv2World.initIfNeeded(LV2_PATH);
  5357. else
  5358. lv2World.initIfNeeded(LILV_DEFAULT_LV2_PATH);
  5359. // ---------------------------------------------------------------
  5360. // get plugin from lv2_rdf (lilv)
  5361. fRdfDescriptor = lv2_rdf_new(uri, true);
  5362. if (fRdfDescriptor == nullptr)
  5363. {
  5364. pData->engine->setLastError("Failed to find the requested plugin");
  5365. return false;
  5366. }
  5367. #ifdef ADAPT_FOR_APPLE_SILLICON
  5368. // ---------------------------------------------------------------
  5369. // check if we can open this binary, might need a bridge
  5370. {
  5371. const CarlaMagic magic;
  5372. if (const char* const output = magic.getFileDescription(fRdfDescriptor->Binary))
  5373. {
  5374. # ifdef __aarch64__
  5375. if (std::strstr(output, "arm64") == nullptr && std::strstr(output, "x86_64") != nullptr)
  5376. needsArchBridge = "x86_64";
  5377. # else
  5378. if (std::strstr(output, "x86_64") == nullptr && std::strstr(output, "arm64") != nullptr)
  5379. needsArchBridge = "arm64";
  5380. # endif
  5381. if (needsArchBridge != nullptr)
  5382. return false;
  5383. }
  5384. }
  5385. #endif // ADAPT_FOR_APPLE_SILLICON
  5386. // ---------------------------------------------------------------
  5387. // open DLL
  5388. #ifdef CARLA_OS_MAC
  5389. // Binary might be in quarentine due to Apple stupid notarization rules, let's remove that if possible
  5390. removeFileFromQuarantine(fRdfDescriptor->Binary);
  5391. #endif
  5392. if (! pData->libOpen(fRdfDescriptor->Binary))
  5393. {
  5394. pData->engine->setLastError(pData->libError(fRdfDescriptor->Binary));
  5395. return false;
  5396. }
  5397. // ---------------------------------------------------------------
  5398. // try to get DLL main entry via new mode
  5399. if (const LV2_Lib_Descriptor_Function libDescFn = pData->libSymbol<LV2_Lib_Descriptor_Function>("lv2_lib_descriptor"))
  5400. {
  5401. // -----------------------------------------------------------
  5402. // all ok, get lib descriptor
  5403. const LV2_Lib_Descriptor* const libDesc = libDescFn(fRdfDescriptor->Bundle, nullptr);
  5404. if (libDesc == nullptr)
  5405. {
  5406. pData->engine->setLastError("Could not find the LV2 Descriptor");
  5407. return false;
  5408. }
  5409. // -----------------------------------------------------------
  5410. // get descriptor that matches URI (new mode)
  5411. uint32_t i = 0;
  5412. while ((fDescriptor = libDesc->get_plugin(libDesc->handle, i++)))
  5413. {
  5414. if (std::strcmp(fDescriptor->URI, uri) == 0)
  5415. break;
  5416. }
  5417. }
  5418. else
  5419. {
  5420. // -----------------------------------------------------------
  5421. // get DLL main entry (old mode)
  5422. const LV2_Descriptor_Function descFn = pData->libSymbol<LV2_Descriptor_Function>("lv2_descriptor");
  5423. if (descFn == nullptr)
  5424. {
  5425. pData->engine->setLastError("Could not find the LV2 Descriptor in the plugin library");
  5426. return false;
  5427. }
  5428. // -----------------------------------------------------------
  5429. // get descriptor that matches URI (old mode)
  5430. uint32_t i = 0;
  5431. while ((fDescriptor = descFn(i++)))
  5432. {
  5433. if (std::strcmp(fDescriptor->URI, uri) == 0)
  5434. break;
  5435. }
  5436. }
  5437. if (fDescriptor == nullptr)
  5438. {
  5439. pData->engine->setLastError("Could not find the requested plugin URI in the plugin library");
  5440. return false;
  5441. }
  5442. // ---------------------------------------------------------------
  5443. // check supported port-types and features
  5444. bool canContinue = true;
  5445. // Check supported ports
  5446. for (uint32_t j=0; j < fRdfDescriptor->PortCount; ++j)
  5447. {
  5448. const LV2_Property portTypes(fRdfDescriptor->Ports[j].Types);
  5449. if (! is_lv2_port_supported(portTypes))
  5450. {
  5451. if (! LV2_IS_PORT_OPTIONAL(fRdfDescriptor->Ports[j].Properties))
  5452. {
  5453. pData->engine->setLastError("Plugin requires a port type that is not currently supported");
  5454. canContinue = false;
  5455. break;
  5456. }
  5457. }
  5458. }
  5459. // Check supported features
  5460. for (uint32_t j=0; j < fRdfDescriptor->FeatureCount && canContinue; ++j)
  5461. {
  5462. const LV2_RDF_Feature& feature(fRdfDescriptor->Features[j]);
  5463. if (std::strcmp(feature.URI, LV2_DATA_ACCESS_URI) == 0 || std::strcmp(feature.URI, LV2_INSTANCE_ACCESS_URI) == 0)
  5464. {
  5465. carla_stderr("Plugin DSP wants UI feature '%s', ignoring this", feature.URI);
  5466. }
  5467. else if (std::strcmp(feature.URI, LV2_BUF_SIZE__fixedBlockLength) == 0)
  5468. {
  5469. fNeedsFixedBuffers = true;
  5470. }
  5471. else if (std::strcmp(feature.URI, LV2_PORT_PROPS__supportsStrictBounds) == 0)
  5472. {
  5473. fStrictBounds = feature.Required ? 1 : 0;
  5474. }
  5475. else if (std::strcmp(feature.URI, LV2_STATE__loadDefaultState) == 0)
  5476. {
  5477. fHasLoadDefaultState = true;
  5478. }
  5479. else if (std::strcmp(feature.URI, LV2_STATE__threadSafeRestore) == 0)
  5480. {
  5481. fHasThreadSafeRestore = true;
  5482. }
  5483. else if (feature.Required && ! is_lv2_feature_supported(feature.URI))
  5484. {
  5485. CarlaString msg("Plugin wants a feature that is not supported:\n");
  5486. msg += feature.URI;
  5487. canContinue = false;
  5488. pData->engine->setLastError(msg);
  5489. break;
  5490. }
  5491. }
  5492. if (! canContinue)
  5493. {
  5494. // error already set
  5495. return false;
  5496. }
  5497. if (fNeedsFixedBuffers && ! pData->engine->usesConstantBufferSize())
  5498. {
  5499. pData->engine->setLastError("Cannot use this plugin under the current engine.\n"
  5500. "The plugin requires a fixed block size which is not possible right now.");
  5501. return false;
  5502. }
  5503. // ---------------------------------------------------------------
  5504. // set icon
  5505. if (std::strncmp(fDescriptor->URI, "http://distrho.sf.net/", 22) == 0)
  5506. pData->iconName = carla_strdup_safe("distrho");
  5507. // ---------------------------------------------------------------
  5508. // set info
  5509. if (name != nullptr && name[0] != '\0')
  5510. pData->name = pData->engine->getUniquePluginName(name);
  5511. else
  5512. pData->name = pData->engine->getUniquePluginName(fRdfDescriptor->Name);
  5513. // ---------------------------------------------------------------
  5514. // register client
  5515. pData->client = pData->engine->addClient(plugin);
  5516. if (pData->client == nullptr || ! pData->client->isOk())
  5517. {
  5518. pData->engine->setLastError("Failed to register plugin client");
  5519. return false;
  5520. }
  5521. // ---------------------------------------------------------------
  5522. // initialize options
  5523. const int bufferSize = static_cast<int>(pData->engine->getBufferSize());
  5524. fLv2Options.minBufferSize = fNeedsFixedBuffers ? bufferSize : 1;
  5525. fLv2Options.maxBufferSize = bufferSize;
  5526. fLv2Options.nominalBufferSize = bufferSize;
  5527. fLv2Options.sampleRate = static_cast<float>(pData->engine->getSampleRate());
  5528. fLv2Options.transientWinId = static_cast<int64_t>(opts.frontendWinId);
  5529. uint32_t eventBufferSize = MAX_DEFAULT_BUFFER_SIZE;
  5530. for (uint32_t j=0; j < fRdfDescriptor->PortCount; ++j)
  5531. {
  5532. const LV2_Property portTypes(fRdfDescriptor->Ports[j].Types);
  5533. if (LV2_IS_PORT_ATOM_SEQUENCE(portTypes) || LV2_IS_PORT_EVENT(portTypes) || LV2_IS_PORT_MIDI_LL(portTypes))
  5534. {
  5535. if (fRdfDescriptor->Ports[j].MinimumSize > eventBufferSize)
  5536. eventBufferSize = fRdfDescriptor->Ports[j].MinimumSize;
  5537. }
  5538. }
  5539. fLv2Options.sequenceSize = static_cast<int>(eventBufferSize);
  5540. fLv2Options.bgColor = opts.bgColor;
  5541. fLv2Options.fgColor = opts.fgColor;
  5542. fLv2Options.uiScale = opts.uiScale;
  5543. // ---------------------------------------------------------------
  5544. // initialize features (part 1)
  5545. LV2_Event_Feature* const eventFt = new LV2_Event_Feature;
  5546. eventFt->callback_data = this;
  5547. eventFt->lv2_event_ref = carla_lv2_event_ref;
  5548. eventFt->lv2_event_unref = carla_lv2_event_unref;
  5549. LV2_Log_Log* const logFt = new LV2_Log_Log;
  5550. logFt->handle = this;
  5551. logFt->printf = carla_lv2_log_printf;
  5552. logFt->vprintf = carla_lv2_log_vprintf;
  5553. LV2_State_Free_Path* const stateFreePathFt = new LV2_State_Free_Path;
  5554. stateFreePathFt->handle = this;
  5555. stateFreePathFt->free_path = carla_lv2_state_free_path;
  5556. LV2_State_Make_Path* const stateMakePathFt = new LV2_State_Make_Path;
  5557. stateMakePathFt->handle = this;
  5558. stateMakePathFt->path = carla_lv2_state_make_path_tmp;
  5559. LV2_State_Map_Path* const stateMapPathFt = new LV2_State_Map_Path;
  5560. stateMapPathFt->handle = this;
  5561. stateMapPathFt->abstract_path = carla_lv2_state_map_to_abstract_path_tmp;
  5562. stateMapPathFt->absolute_path = carla_lv2_state_map_to_absolute_path_tmp;
  5563. LV2_Programs_Host* const programsFt = new LV2_Programs_Host;
  5564. programsFt->handle = this;
  5565. programsFt->program_changed = carla_lv2_program_changed;
  5566. LV2_Resize_Port_Resize* const rsPortFt = new LV2_Resize_Port_Resize;
  5567. rsPortFt->data = this;
  5568. rsPortFt->resize = carla_lv2_resize_port;
  5569. LV2_RtMemPool_Pool* const rtMemPoolFt = new LV2_RtMemPool_Pool;
  5570. lv2_rtmempool_init(rtMemPoolFt);
  5571. LV2_RtMemPool_Pool_Deprecated* const rtMemPoolOldFt = new LV2_RtMemPool_Pool_Deprecated;
  5572. lv2_rtmempool_init_deprecated(rtMemPoolOldFt);
  5573. LV2_URI_Map_Feature* const uriMapFt = new LV2_URI_Map_Feature;
  5574. uriMapFt->callback_data = this;
  5575. uriMapFt->uri_to_id = carla_lv2_uri_to_id;
  5576. LV2_URID_Map* const uridMapFt = new LV2_URID_Map;
  5577. uridMapFt->handle = this;
  5578. uridMapFt->map = carla_lv2_urid_map;
  5579. LV2_URID_Unmap* const uridUnmapFt = new LV2_URID_Unmap;
  5580. uridUnmapFt->handle = this;
  5581. uridUnmapFt->unmap = carla_lv2_urid_unmap;
  5582. LV2_Worker_Schedule* const workerFt = new LV2_Worker_Schedule;
  5583. workerFt->handle = this;
  5584. workerFt->schedule_work = carla_lv2_worker_schedule;
  5585. LV2_Inline_Display* const inlineDisplay = new LV2_Inline_Display;
  5586. inlineDisplay->handle = this;
  5587. inlineDisplay->queue_draw = carla_lv2_inline_display_queue_draw;
  5588. LV2_Midnam* const midnam = new LV2_Midnam;
  5589. midnam->handle = this;
  5590. midnam->update = carla_lv2_midnam_update;
  5591. // ---------------------------------------------------------------
  5592. // initialize features (part 2)
  5593. for (uint32_t j=0; j < kFeatureCountPlugin; ++j)
  5594. fFeatures[j] = new LV2_Feature;
  5595. fFeatures[kFeatureIdBufSizeBounded]->URI = LV2_BUF_SIZE__boundedBlockLength;
  5596. fFeatures[kFeatureIdBufSizeBounded]->data = nullptr;
  5597. fFeatures[kFeatureIdBufSizeFixed]->URI = fNeedsFixedBuffers
  5598. ? LV2_BUF_SIZE__fixedBlockLength
  5599. : LV2_BUF_SIZE__boundedBlockLength;
  5600. fFeatures[kFeatureIdBufSizeFixed]->data = nullptr;
  5601. fFeatures[kFeatureIdBufSizePowerOf2]->URI = LV2_BUF_SIZE__powerOf2BlockLength;
  5602. fFeatures[kFeatureIdBufSizePowerOf2]->data = nullptr;
  5603. fFeatures[kFeatureIdEvent]->URI = LV2_EVENT_URI;
  5604. fFeatures[kFeatureIdEvent]->data = eventFt;
  5605. fFeatures[kFeatureIdHardRtCapable]->URI = LV2_CORE__hardRTCapable;
  5606. fFeatures[kFeatureIdHardRtCapable]->data = nullptr;
  5607. fFeatures[kFeatureIdInPlaceBroken]->URI = LV2_CORE__inPlaceBroken;
  5608. fFeatures[kFeatureIdInPlaceBroken]->data = nullptr;
  5609. fFeatures[kFeatureIdIsLive]->URI = LV2_CORE__isLive;
  5610. fFeatures[kFeatureIdIsLive]->data = nullptr;
  5611. fFeatures[kFeatureIdLogs]->URI = LV2_LOG__log;
  5612. fFeatures[kFeatureIdLogs]->data = logFt;
  5613. fFeatures[kFeatureIdOptions]->URI = LV2_OPTIONS__options;
  5614. fFeatures[kFeatureIdOptions]->data = fLv2Options.opts;
  5615. fFeatures[kFeatureIdPrograms]->URI = LV2_PROGRAMS__Host;
  5616. fFeatures[kFeatureIdPrograms]->data = programsFt;
  5617. fFeatures[kFeatureIdResizePort]->URI = LV2_RESIZE_PORT__resize;
  5618. fFeatures[kFeatureIdResizePort]->data = rsPortFt;
  5619. fFeatures[kFeatureIdRtMemPool]->URI = LV2_RTSAFE_MEMORY_POOL__Pool;
  5620. fFeatures[kFeatureIdRtMemPool]->data = rtMemPoolFt;
  5621. fFeatures[kFeatureIdRtMemPoolOld]->URI = LV2_RTSAFE_MEMORY_POOL_DEPRECATED_URI;
  5622. fFeatures[kFeatureIdRtMemPoolOld]->data = rtMemPoolOldFt;
  5623. fFeatures[kFeatureIdStateFreePath]->URI = LV2_STATE__freePath;
  5624. fFeatures[kFeatureIdStateFreePath]->data = stateFreePathFt;
  5625. fFeatures[kFeatureIdStateMakePath]->URI = LV2_STATE__makePath;
  5626. fFeatures[kFeatureIdStateMakePath]->data = stateMakePathFt;
  5627. fFeatures[kFeatureIdStateMapPath]->URI = LV2_STATE__mapPath;
  5628. fFeatures[kFeatureIdStateMapPath]->data = stateMapPathFt;
  5629. fFeatures[kFeatureIdStrictBounds]->URI = LV2_PORT_PROPS__supportsStrictBounds;
  5630. fFeatures[kFeatureIdStrictBounds]->data = nullptr;
  5631. fFeatures[kFeatureIdUriMap]->URI = LV2_URI_MAP_URI;
  5632. fFeatures[kFeatureIdUriMap]->data = uriMapFt;
  5633. fFeatures[kFeatureIdUridMap]->URI = LV2_URID__map;
  5634. fFeatures[kFeatureIdUridMap]->data = uridMapFt;
  5635. fFeatures[kFeatureIdUridUnmap]->URI = LV2_URID__unmap;
  5636. fFeatures[kFeatureIdUridUnmap]->data = uridUnmapFt;
  5637. fFeatures[kFeatureIdWorker]->URI = LV2_WORKER__schedule;
  5638. fFeatures[kFeatureIdWorker]->data = workerFt;
  5639. fFeatures[kFeatureIdInlineDisplay]->URI = LV2_INLINEDISPLAY__queue_draw;
  5640. fFeatures[kFeatureIdInlineDisplay]->data = inlineDisplay;
  5641. fFeatures[kFeatureIdMidnam]->URI = LV2_MIDNAM__update;
  5642. fFeatures[kFeatureIdMidnam]->data = midnam;
  5643. // ---------------------------------------------------------------
  5644. // initialize features (part 3)
  5645. LV2_State_Make_Path* const stateMakePathFt2 = new LV2_State_Make_Path;
  5646. stateMakePathFt2->handle = this;
  5647. stateMakePathFt2->path = carla_lv2_state_make_path_real;
  5648. LV2_State_Map_Path* const stateMapPathFt2 = new LV2_State_Map_Path;
  5649. stateMapPathFt2->handle = this;
  5650. stateMapPathFt2->abstract_path = carla_lv2_state_map_to_abstract_path_real;
  5651. stateMapPathFt2->absolute_path = carla_lv2_state_map_to_absolute_path_real;
  5652. for (uint32_t j=0; j < kStateFeatureCountAll; ++j)
  5653. fStateFeatures[j] = new LV2_Feature;
  5654. fStateFeatures[kStateFeatureIdFreePath]->URI = LV2_STATE__freePath;
  5655. fStateFeatures[kStateFeatureIdFreePath]->data = stateFreePathFt;
  5656. fStateFeatures[kStateFeatureIdMakePath]->URI = LV2_STATE__makePath;
  5657. fStateFeatures[kStateFeatureIdMakePath]->data = stateMakePathFt2;
  5658. fStateFeatures[kStateFeatureIdMapPath]->URI = LV2_STATE__mapPath;
  5659. fStateFeatures[kStateFeatureIdMapPath]->data = stateMapPathFt2;
  5660. fStateFeatures[kStateFeatureIdWorker]->URI = LV2_WORKER__schedule;
  5661. fStateFeatures[kStateFeatureIdWorker]->data = workerFt;
  5662. // ---------------------------------------------------------------
  5663. // initialize plugin
  5664. try {
  5665. fHandle = fDescriptor->instantiate(fDescriptor, pData->engine->getSampleRate(), fRdfDescriptor->Bundle, fFeatures);
  5666. } catch(...) {}
  5667. if (fHandle == nullptr)
  5668. {
  5669. pData->engine->setLastError("Plugin failed to initialize");
  5670. return false;
  5671. }
  5672. recheckExtensions();
  5673. // ---------------------------------------------------------------
  5674. // set options
  5675. pData->options = 0x0;
  5676. if (fLatencyIndex >= 0 || getMidiOutCount() != 0 || fNeedsFixedBuffers)
  5677. pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
  5678. else if (options & PLUGIN_OPTION_FIXED_BUFFERS)
  5679. pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
  5680. if (opts.forceStereo)
  5681. pData->options |= PLUGIN_OPTION_FORCE_STEREO;
  5682. else if (options & PLUGIN_OPTION_FORCE_STEREO)
  5683. pData->options |= PLUGIN_OPTION_FORCE_STEREO;
  5684. if (getMidiInCount() != 0)
  5685. {
  5686. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_CONTROL_CHANGES))
  5687. pData->options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  5688. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_CHANNEL_PRESSURE))
  5689. pData->options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  5690. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH))
  5691. pData->options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  5692. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_PITCHBEND))
  5693. pData->options |= PLUGIN_OPTION_SEND_PITCHBEND;
  5694. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_ALL_SOUND_OFF))
  5695. pData->options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  5696. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_PROGRAM_CHANGES))
  5697. pData->options |= PLUGIN_OPTION_SEND_PROGRAM_CHANGES;
  5698. if (isPluginOptionInverseEnabled(options, PLUGIN_OPTION_SKIP_SENDING_NOTES))
  5699. pData->options |= PLUGIN_OPTION_SKIP_SENDING_NOTES;
  5700. }
  5701. if (fExt.programs != nullptr && (pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES) == 0)
  5702. {
  5703. if (isPluginOptionEnabled(options, PLUGIN_OPTION_MAP_PROGRAM_CHANGES))
  5704. pData->options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  5705. }
  5706. // ---------------------------------------------------------------
  5707. // gui stuff
  5708. if (fRdfDescriptor->UICount != 0)
  5709. initUi();
  5710. return true;
  5711. // might be unused
  5712. (void)needsArchBridge;
  5713. }
  5714. // -------------------------------------------------------------------
  5715. void initUi()
  5716. {
  5717. // ---------------------------------------------------------------
  5718. // find the most appropriate ui
  5719. int eQt4, eQt5, eGtk2, eGtk3, eCocoa, eWindows, eX11, eMod, iCocoa, iWindows, iX11, iExt, iFinal;
  5720. eQt4 = eQt5 = eGtk2 = eGtk3 = eCocoa = eWindows = eX11 = eMod = iCocoa = iWindows = iX11 = iExt = iFinal = -1;
  5721. #if defined(LV2_UIS_ONLY_BRIDGES)
  5722. const bool preferUiBridges = true;
  5723. #elif defined(BUILD_BRIDGE)
  5724. const bool preferUiBridges = false;
  5725. #else
  5726. const bool preferUiBridges = pData->engine->getOptions().preferUiBridges;
  5727. #endif
  5728. bool hasShowInterface = false;
  5729. for (uint32_t i=0; i < fRdfDescriptor->UICount; ++i)
  5730. {
  5731. CARLA_SAFE_ASSERT_CONTINUE(fRdfDescriptor->UIs[i].URI != nullptr);
  5732. const int ii(static_cast<int>(i));
  5733. switch (fRdfDescriptor->UIs[i].Type)
  5734. {
  5735. case LV2_UI_QT4:
  5736. if (isUiBridgeable(i))
  5737. eQt4 = ii;
  5738. break;
  5739. case LV2_UI_QT5:
  5740. if (isUiBridgeable(i))
  5741. eQt5 = ii;
  5742. break;
  5743. case LV2_UI_GTK2:
  5744. if (isUiBridgeable(i))
  5745. eGtk2 = ii;
  5746. break;
  5747. case LV2_UI_GTK3:
  5748. if (isUiBridgeable(i))
  5749. eGtk3 = ii;
  5750. break;
  5751. #ifdef CARLA_OS_MAC
  5752. case LV2_UI_COCOA:
  5753. if (isUiBridgeable(i) && preferUiBridges)
  5754. eCocoa = ii;
  5755. iCocoa = ii;
  5756. break;
  5757. #endif
  5758. #ifdef CARLA_OS_WIN
  5759. case LV2_UI_WINDOWS:
  5760. if (isUiBridgeable(i) && preferUiBridges)
  5761. eWindows = ii;
  5762. iWindows = ii;
  5763. break;
  5764. #endif
  5765. case LV2_UI_X11:
  5766. if (isUiBridgeable(i) && preferUiBridges)
  5767. eX11 = ii;
  5768. iX11 = ii;
  5769. break;
  5770. case LV2_UI_EXTERNAL:
  5771. case LV2_UI_OLD_EXTERNAL:
  5772. iExt = ii;
  5773. break;
  5774. case LV2_UI_MOD:
  5775. eMod = ii;
  5776. break;
  5777. default:
  5778. break;
  5779. }
  5780. }
  5781. /**/ if (eQt4 >= 0)
  5782. iFinal = eQt4;
  5783. else if (eQt5 >= 0)
  5784. iFinal = eQt5;
  5785. else if (eGtk2 >= 0)
  5786. iFinal = eGtk2;
  5787. else if (eGtk3 >= 0)
  5788. iFinal = eGtk3;
  5789. #ifdef CARLA_OS_MAC
  5790. else if (eCocoa >= 0)
  5791. iFinal = eCocoa;
  5792. #endif
  5793. #ifdef CARLA_OS_WIN
  5794. else if (eWindows >= 0)
  5795. iFinal = eWindows;
  5796. #endif
  5797. #ifdef HAVE_X11
  5798. else if (eX11 >= 0)
  5799. iFinal = eX11;
  5800. #endif
  5801. #ifndef LV2_UIS_ONLY_BRIDGES
  5802. # ifdef CARLA_OS_MAC
  5803. else if (iCocoa >= 0)
  5804. iFinal = iCocoa;
  5805. # endif
  5806. # ifdef CARLA_OS_WIN
  5807. else if (iWindows >= 0)
  5808. iFinal = iWindows;
  5809. # endif
  5810. # ifdef HAVE_X11
  5811. else if (iX11 >= 0)
  5812. iFinal = iX11;
  5813. # endif
  5814. #endif
  5815. else if (iExt >= 0)
  5816. iFinal = iExt;
  5817. #ifndef BUILD_BRIDGE
  5818. if (iFinal < 0)
  5819. #endif
  5820. {
  5821. // no suitable UI found, see if there's one which supports ui:showInterface
  5822. for (uint32_t i=0; i < fRdfDescriptor->UICount && ! hasShowInterface; ++i)
  5823. {
  5824. LV2_RDF_UI* const ui(&fRdfDescriptor->UIs[i]);
  5825. for (uint32_t j=0; j < ui->ExtensionCount; ++j)
  5826. {
  5827. CARLA_SAFE_ASSERT_CONTINUE(ui->Extensions[j] != nullptr);
  5828. if (std::strcmp(ui->Extensions[j], LV2_UI__showInterface) != 0)
  5829. continue;
  5830. iFinal = static_cast<int>(i);
  5831. hasShowInterface = true;
  5832. break;
  5833. }
  5834. }
  5835. if (iFinal < 0)
  5836. {
  5837. if (eMod < 0)
  5838. {
  5839. carla_stderr("Failed to find an appropriate LV2 UI for this plugin");
  5840. return;
  5841. }
  5842. // use MODGUI as last resort
  5843. iFinal = eMod;
  5844. }
  5845. }
  5846. fUI.rdfDescriptor = &fRdfDescriptor->UIs[iFinal];
  5847. // ---------------------------------------------------------------
  5848. // check supported ui features
  5849. bool canContinue = true;
  5850. bool canDelete = true;
  5851. for (uint32_t i=0; i < fUI.rdfDescriptor->FeatureCount; ++i)
  5852. {
  5853. const char* const uri(fUI.rdfDescriptor->Features[i].URI);
  5854. CARLA_SAFE_ASSERT_CONTINUE(uri != nullptr && uri[0] != '\0');
  5855. if (! is_lv2_ui_feature_supported(uri))
  5856. {
  5857. if (fUI.rdfDescriptor->Features[i].Required)
  5858. {
  5859. carla_stderr("Plugin UI requires a feature that is not supported:\n%s", uri);
  5860. canContinue = false;
  5861. break;
  5862. }
  5863. carla_stderr("Plugin UI wants a feature that is not supported (ignored):\n%s", uri);
  5864. }
  5865. if (std::strcmp(uri, LV2_UI__makeResident) == 0 || std::strcmp(uri, LV2_UI__makeSONameResident) == 0)
  5866. canDelete = false;
  5867. else if (std::strcmp(uri, LV2_UI__requestValue) == 0)
  5868. pData->hints |= PLUGIN_NEEDS_UI_MAIN_THREAD;
  5869. }
  5870. if (! canContinue)
  5871. {
  5872. fUI.rdfDescriptor = nullptr;
  5873. return;
  5874. }
  5875. // ---------------------------------------------------------------
  5876. // initialize ui according to type
  5877. const LV2_Property uiType = fUI.rdfDescriptor->Type;
  5878. #ifndef LV2_UIS_ONLY_INPROCESS
  5879. if (
  5880. (iFinal == eQt4 ||
  5881. iFinal == eQt5 ||
  5882. iFinal == eGtk2 ||
  5883. iFinal == eGtk3 ||
  5884. iFinal == eCocoa ||
  5885. iFinal == eWindows ||
  5886. iFinal == eX11 ||
  5887. iFinal == eMod)
  5888. #ifdef BUILD_BRIDGE
  5889. && ! hasShowInterface
  5890. #endif
  5891. )
  5892. {
  5893. // -----------------------------------------------------------
  5894. // initialize ui-bridge
  5895. if (const char* const bridgeBinary = getUiBridgeBinary(uiType))
  5896. {
  5897. carla_stdout("Will use UI-Bridge for '%s', binary: \"%s\"", pData->name, bridgeBinary);
  5898. CarlaString uiTitle;
  5899. if (pData->uiTitle.isNotEmpty())
  5900. {
  5901. uiTitle = pData->uiTitle;
  5902. }
  5903. else
  5904. {
  5905. uiTitle = pData->name;
  5906. uiTitle += " (GUI)";
  5907. }
  5908. fLv2Options.windowTitle = uiTitle.releaseBufferPointer();
  5909. fUI.type = UI::TYPE_BRIDGE;
  5910. fPipeServer.setData(bridgeBinary, fRdfDescriptor->URI, fUI.rdfDescriptor->URI);
  5911. delete[] bridgeBinary;
  5912. return;
  5913. }
  5914. if (iFinal == eQt4 || iFinal == eQt5 || iFinal == eGtk2 || iFinal == eGtk3 || iFinal == eMod)
  5915. {
  5916. carla_stderr2("Failed to find UI bridge binary for '%s', cannot use UI", pData->name);
  5917. fUI.rdfDescriptor = nullptr;
  5918. return;
  5919. }
  5920. }
  5921. #endif
  5922. #ifdef LV2_UIS_ONLY_BRIDGES
  5923. carla_stderr2("Failed to get an UI working, canBridge:%s", bool2str(isUiBridgeable(static_cast<uint32_t>(iFinal))));
  5924. fUI.rdfDescriptor = nullptr;
  5925. return;
  5926. #endif
  5927. // ---------------------------------------------------------------
  5928. // open UI DLL
  5929. #ifdef CARLA_OS_MAC
  5930. // Binary might be in quarentine due to Apple stupid notarization rules, let's remove that if possible
  5931. removeFileFromQuarantine(fUI.rdfDescriptor->Binary);
  5932. #endif
  5933. if (! pData->uiLibOpen(fUI.rdfDescriptor->Binary, canDelete))
  5934. {
  5935. carla_stderr2("Could not load UI library, error was:\n%s", pData->libError(fUI.rdfDescriptor->Binary));
  5936. fUI.rdfDescriptor = nullptr;
  5937. return;
  5938. }
  5939. // ---------------------------------------------------------------
  5940. // get UI DLL main entry
  5941. LV2UI_DescriptorFunction uiDescFn = pData->uiLibSymbol<LV2UI_DescriptorFunction>("lv2ui_descriptor");
  5942. if (uiDescFn == nullptr)
  5943. {
  5944. carla_stderr2("Could not find the LV2UI Descriptor in the UI library");
  5945. pData->uiLibClose();
  5946. fUI.rdfDescriptor = nullptr;
  5947. return;
  5948. }
  5949. // ---------------------------------------------------------------
  5950. // get UI descriptor that matches UI URI
  5951. uint32_t i = 0;
  5952. while ((fUI.descriptor = uiDescFn(i++)))
  5953. {
  5954. if (std::strcmp(fUI.descriptor->URI, fUI.rdfDescriptor->URI) == 0)
  5955. break;
  5956. }
  5957. if (fUI.descriptor == nullptr)
  5958. {
  5959. carla_stderr2("Could not find the requested GUI in the plugin UI library");
  5960. pData->uiLibClose();
  5961. fUI.rdfDescriptor = nullptr;
  5962. return;
  5963. }
  5964. // ---------------------------------------------------------------
  5965. // check if ui is usable
  5966. switch (uiType)
  5967. {
  5968. case LV2_UI_NONE:
  5969. carla_stdout("Will use LV2 Show Interface for '%s'", pData->name);
  5970. fUI.type = UI::TYPE_EMBED;
  5971. break;
  5972. case LV2_UI_QT4:
  5973. carla_stdout("Will use LV2 Qt4 UI for '%s', NOT!", pData->name);
  5974. fUI.type = UI::TYPE_EMBED;
  5975. break;
  5976. case LV2_UI_QT5:
  5977. carla_stdout("Will use LV2 Qt5 UI for '%s', NOT!", pData->name);
  5978. fUI.type = UI::TYPE_EMBED;
  5979. break;
  5980. case LV2_UI_GTK2:
  5981. carla_stdout("Will use LV2 Gtk2 UI for '%s', NOT!", pData->name);
  5982. fUI.type = UI::TYPE_EMBED;
  5983. break;
  5984. case LV2_UI_GTK3:
  5985. carla_stdout("Will use LV2 Gtk3 UI for '%s', NOT!", pData->name);
  5986. fUI.type = UI::TYPE_EMBED;
  5987. break;
  5988. #ifdef CARLA_OS_MAC
  5989. case LV2_UI_COCOA:
  5990. carla_stdout("Will use LV2 Cocoa UI for '%s'", pData->name);
  5991. fUI.type = UI::TYPE_EMBED;
  5992. break;
  5993. #endif
  5994. #ifdef CARLA_OS_WIN
  5995. case LV2_UI_WINDOWS:
  5996. carla_stdout("Will use LV2 Windows UI for '%s'", pData->name);
  5997. fUI.type = UI::TYPE_EMBED;
  5998. break;
  5999. #endif
  6000. case LV2_UI_X11:
  6001. #ifdef HAVE_X11
  6002. carla_stdout("Will use LV2 X11 UI for '%s'", pData->name);
  6003. #else
  6004. carla_stdout("Will use LV2 X11 UI for '%s', NOT!", pData->name);
  6005. #endif
  6006. fUI.type = UI::TYPE_EMBED;
  6007. break;
  6008. case LV2_UI_EXTERNAL:
  6009. case LV2_UI_OLD_EXTERNAL:
  6010. carla_stdout("Will use LV2 External UI for '%s'", pData->name);
  6011. fUI.type = UI::TYPE_EXTERNAL;
  6012. break;
  6013. }
  6014. if (fUI.type == UI::TYPE_NULL)
  6015. {
  6016. pData->uiLibClose();
  6017. fUI.descriptor = nullptr;
  6018. fUI.rdfDescriptor = nullptr;
  6019. return;
  6020. }
  6021. // ---------------------------------------------------------------
  6022. // initialize ui data
  6023. {
  6024. CarlaString uiTitle;
  6025. if (pData->uiTitle.isNotEmpty())
  6026. {
  6027. uiTitle = pData->uiTitle;
  6028. }
  6029. else
  6030. {
  6031. uiTitle = pData->name;
  6032. uiTitle += " (GUI)";
  6033. }
  6034. fLv2Options.windowTitle = uiTitle.releaseBufferPointer();
  6035. }
  6036. fLv2Options.opts[CarlaPluginLV2Options::WindowTitle].size = (uint32_t)std::strlen(fLv2Options.windowTitle);
  6037. fLv2Options.opts[CarlaPluginLV2Options::WindowTitle].value = fLv2Options.windowTitle;
  6038. // ---------------------------------------------------------------
  6039. // initialize ui features (part 1)
  6040. LV2_Extension_Data_Feature* const uiDataFt = new LV2_Extension_Data_Feature;
  6041. uiDataFt->data_access = fDescriptor->extension_data;
  6042. LV2UI_Port_Map* const uiPortMapFt = new LV2UI_Port_Map;
  6043. uiPortMapFt->handle = this;
  6044. uiPortMapFt->port_index = carla_lv2_ui_port_map;
  6045. LV2UI_Request_Value* const uiRequestValueFt = new LV2UI_Request_Value;
  6046. uiRequestValueFt->handle = this;
  6047. uiRequestValueFt->request = carla_lv2_ui_request_value;
  6048. LV2UI_Resize* const uiResizeFt = new LV2UI_Resize;
  6049. uiResizeFt->handle = this;
  6050. uiResizeFt->ui_resize = carla_lv2_ui_resize;
  6051. LV2UI_Touch* const uiTouchFt = new LV2UI_Touch;
  6052. uiTouchFt->handle = this;
  6053. uiTouchFt->touch = carla_lv2_ui_touch;
  6054. LV2_External_UI_Host* const uiExternalHostFt = new LV2_External_UI_Host;
  6055. uiExternalHostFt->ui_closed = carla_lv2_external_ui_closed;
  6056. uiExternalHostFt->plugin_human_id = fLv2Options.windowTitle;
  6057. // ---------------------------------------------------------------
  6058. // initialize ui features (part 2)
  6059. for (uint32_t j=kFeatureCountPlugin; j < kFeatureCountAll; ++j)
  6060. fFeatures[j] = new LV2_Feature;
  6061. fFeatures[kFeatureIdUiDataAccess]->URI = LV2_DATA_ACCESS_URI;
  6062. fFeatures[kFeatureIdUiDataAccess]->data = uiDataFt;
  6063. fFeatures[kFeatureIdUiInstanceAccess]->URI = LV2_INSTANCE_ACCESS_URI;
  6064. fFeatures[kFeatureIdUiInstanceAccess]->data = fHandle;
  6065. fFeatures[kFeatureIdUiIdleInterface]->URI = LV2_UI__idleInterface;
  6066. fFeatures[kFeatureIdUiIdleInterface]->data = nullptr;
  6067. fFeatures[kFeatureIdUiFixedSize]->URI = LV2_UI__fixedSize;
  6068. fFeatures[kFeatureIdUiFixedSize]->data = nullptr;
  6069. fFeatures[kFeatureIdUiMakeResident]->URI = LV2_UI__makeResident;
  6070. fFeatures[kFeatureIdUiMakeResident]->data = nullptr;
  6071. fFeatures[kFeatureIdUiMakeResident2]->URI = LV2_UI__makeSONameResident;
  6072. fFeatures[kFeatureIdUiMakeResident2]->data = nullptr;
  6073. fFeatures[kFeatureIdUiNoUserResize]->URI = LV2_UI__noUserResize;
  6074. fFeatures[kFeatureIdUiNoUserResize]->data = nullptr;
  6075. fFeatures[kFeatureIdUiParent]->URI = LV2_UI__parent;
  6076. fFeatures[kFeatureIdUiParent]->data = nullptr;
  6077. fFeatures[kFeatureIdUiPortMap]->URI = LV2_UI__portMap;
  6078. fFeatures[kFeatureIdUiPortMap]->data = uiPortMapFt;
  6079. fFeatures[kFeatureIdUiPortSubscribe]->URI = LV2_UI__portSubscribe;
  6080. fFeatures[kFeatureIdUiPortSubscribe]->data = nullptr;
  6081. fFeatures[kFeatureIdUiRequestValue]->URI = LV2_UI__requestValue;
  6082. fFeatures[kFeatureIdUiRequestValue]->data = uiRequestValueFt;
  6083. fFeatures[kFeatureIdUiResize]->URI = LV2_UI__resize;
  6084. fFeatures[kFeatureIdUiResize]->data = uiResizeFt;
  6085. fFeatures[kFeatureIdUiTouch]->URI = LV2_UI__touch;
  6086. fFeatures[kFeatureIdUiTouch]->data = uiTouchFt;
  6087. fFeatures[kFeatureIdExternalUi]->URI = LV2_EXTERNAL_UI__Host;
  6088. fFeatures[kFeatureIdExternalUi]->data = uiExternalHostFt;
  6089. fFeatures[kFeatureIdExternalUiOld]->URI = LV2_EXTERNAL_UI_DEPRECATED_URI;
  6090. fFeatures[kFeatureIdExternalUiOld]->data = uiExternalHostFt;
  6091. // ---------------------------------------------------------------
  6092. // initialize ui extensions
  6093. if (fUI.descriptor->extension_data == nullptr)
  6094. return;
  6095. fExt.uiidle = (const LV2UI_Idle_Interface*)fUI.descriptor->extension_data(LV2_UI__idleInterface);
  6096. fExt.uishow = (const LV2UI_Show_Interface*)fUI.descriptor->extension_data(LV2_UI__showInterface);
  6097. fExt.uiresize = (const LV2UI_Resize*)fUI.descriptor->extension_data(LV2_UI__resize);
  6098. fExt.uiprograms = (const LV2_Programs_UI_Interface*)fUI.descriptor->extension_data(LV2_PROGRAMS__UIInterface);
  6099. // check if invalid
  6100. if (fExt.uiidle != nullptr && fExt.uiidle->idle == nullptr)
  6101. fExt.uiidle = nullptr;
  6102. if (fExt.uishow != nullptr && (fExt.uishow->show == nullptr || fExt.uishow->hide == nullptr))
  6103. fExt.uishow = nullptr;
  6104. if (fExt.uiresize != nullptr && fExt.uiresize->ui_resize == nullptr)
  6105. fExt.uiresize = nullptr;
  6106. if (fExt.uiprograms != nullptr && fExt.uiprograms->select_program == nullptr)
  6107. fExt.uiprograms = nullptr;
  6108. // don't use uiidle if external
  6109. if (fUI.type == UI::TYPE_EXTERNAL)
  6110. fExt.uiidle = nullptr;
  6111. }
  6112. // -------------------------------------------------------------------
  6113. void handleTransferAtom(const uint32_t portIndex, const LV2_Atom* const atom)
  6114. {
  6115. CARLA_SAFE_ASSERT_RETURN(atom != nullptr,);
  6116. carla_debug("CarlaPluginLV2::handleTransferAtom(%i, %p)", portIndex, atom);
  6117. fAtomBufferEvIn.put(atom, portIndex);
  6118. }
  6119. void handleUridMap(const LV2_URID urid, const char* const uri)
  6120. {
  6121. CARLA_SAFE_ASSERT_RETURN(urid != kUridNull,);
  6122. CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0',);
  6123. carla_debug("CarlaPluginLV2::handleUridMap(%i v " P_SIZE ", \"%s\")", urid, fCustomURIDs.size()-1, uri);
  6124. const std::size_t uriCount(fCustomURIDs.size());
  6125. if (urid < uriCount)
  6126. {
  6127. const char* const ourURI(carla_lv2_urid_unmap(this, urid));
  6128. CARLA_SAFE_ASSERT_RETURN(ourURI != nullptr && ourURI != kUnmapFallback,);
  6129. if (std::strcmp(ourURI, uri) != 0)
  6130. {
  6131. carla_stderr2("PLUGIN :: wrong URI '%s' vs '%s'", ourURI, uri);
  6132. }
  6133. }
  6134. else
  6135. {
  6136. CARLA_SAFE_ASSERT_RETURN(urid == uriCount,);
  6137. fCustomURIDs.push_back(uri);
  6138. }
  6139. }
  6140. // -------------------------------------------------------------------
  6141. void writeAtomPath(const char* const path, const LV2_URID urid)
  6142. {
  6143. uint8_t atomBuf[4096];
  6144. LV2_Atom_Forge atomForge;
  6145. initAtomForge(atomForge);
  6146. lv2_atom_forge_set_buffer(&atomForge, atomBuf, sizeof(atomBuf));
  6147. LV2_Atom_Forge_Frame forgeFrame;
  6148. lv2_atom_forge_object(&atomForge, &forgeFrame, kUridNull, kUridPatchSet);
  6149. lv2_atom_forge_key(&atomForge, kUridCarlaParameterChange);
  6150. lv2_atom_forge_bool(&atomForge, true);
  6151. lv2_atom_forge_key(&atomForge, kUridPatchProperty);
  6152. lv2_atom_forge_urid(&atomForge, urid);
  6153. lv2_atom_forge_key(&atomForge, kUridPatchValue);
  6154. lv2_atom_forge_path(&atomForge, path, static_cast<uint32_t>(std::strlen(path))+1);
  6155. lv2_atom_forge_pop(&atomForge, &forgeFrame);
  6156. LV2_Atom* const atom((LV2_Atom*)atomBuf);
  6157. CARLA_SAFE_ASSERT(atom->size < sizeof(atomBuf));
  6158. fAtomBufferEvIn.put(atom, fEventsIn.ctrlIndex);
  6159. }
  6160. // -------------------------------------------------------------------
  6161. private:
  6162. LV2_Handle fHandle;
  6163. LV2_Handle fHandle2;
  6164. LV2_Feature* fFeatures[kFeatureCountAll+1];
  6165. LV2_Feature* fStateFeatures[kStateFeatureCountAll+1];
  6166. const LV2_Descriptor* fDescriptor;
  6167. const LV2_RDF_Descriptor* fRdfDescriptor;
  6168. float** fAudioInBuffers;
  6169. float** fAudioOutBuffers;
  6170. float** fCvInBuffers;
  6171. float** fCvOutBuffers;
  6172. float* fParamBuffers;
  6173. bool fHasLoadDefaultState : 1;
  6174. bool fHasThreadSafeRestore : 1;
  6175. bool fNeedsFixedBuffers : 1;
  6176. bool fNeedsUiClose : 1;
  6177. bool fInlineDisplayNeedsRedraw : 1;
  6178. int64_t fInlineDisplayLastRedrawTime;
  6179. int32_t fLatencyIndex; // -1 if invalid
  6180. int fStrictBounds; // -1 unsupported, 0 optional, 1 required
  6181. Lv2AtomRingBuffer fAtomBufferEvIn;
  6182. Lv2AtomRingBuffer fAtomBufferUiOut;
  6183. Lv2AtomRingBuffer fAtomBufferWorkerIn;
  6184. Lv2AtomRingBuffer fAtomBufferWorkerResp;
  6185. uint8_t* fAtomBufferUiOutTmpData;
  6186. uint8_t* fAtomBufferWorkerInTmpData;
  6187. LV2_Atom* fAtomBufferRealtime;
  6188. uint32_t fAtomBufferRealtimeSize;
  6189. CarlaPluginLV2EventData fEventsIn;
  6190. CarlaPluginLV2EventData fEventsOut;
  6191. CarlaPluginLV2Options fLv2Options;
  6192. #ifndef LV2_UIS_ONLY_INPROCESS
  6193. CarlaPipeServerLV2 fPipeServer;
  6194. #endif
  6195. std::vector<std::string> fCustomURIDs;
  6196. bool fFirstActive; // first process() call after activate()
  6197. void* fLastStateChunk;
  6198. EngineTimeInfo fLastTimeInfo;
  6199. // if plugin provides path parameter, use it as fake "gui"
  6200. CarlaString fFilePathURI;
  6201. struct Extensions {
  6202. const LV2_Options_Interface* options;
  6203. const LV2_State_Interface* state;
  6204. const LV2_Worker_Interface* worker;
  6205. const LV2_Inline_Display_Interface* inlineDisplay;
  6206. const LV2_Midnam_Interface* midnam;
  6207. const LV2_Programs_Interface* programs;
  6208. const LV2UI_Idle_Interface* uiidle;
  6209. const LV2UI_Show_Interface* uishow;
  6210. const LV2UI_Resize* uiresize;
  6211. const LV2_Programs_UI_Interface* uiprograms;
  6212. Extensions()
  6213. : options(nullptr),
  6214. state(nullptr),
  6215. worker(nullptr),
  6216. inlineDisplay(nullptr),
  6217. midnam(nullptr),
  6218. programs(nullptr),
  6219. uiidle(nullptr),
  6220. uishow(nullptr),
  6221. uiresize(nullptr),
  6222. uiprograms(nullptr) {}
  6223. CARLA_DECLARE_NON_COPYABLE(Extensions);
  6224. } fExt;
  6225. struct UI {
  6226. enum Type {
  6227. TYPE_NULL = 0,
  6228. #ifndef LV2_UIS_ONLY_INPROCESS
  6229. TYPE_BRIDGE,
  6230. #endif
  6231. TYPE_EMBED,
  6232. TYPE_EXTERNAL
  6233. };
  6234. Type type;
  6235. LV2UI_Handle handle;
  6236. LV2UI_Widget widget;
  6237. const LV2UI_Descriptor* descriptor;
  6238. const LV2_RDF_UI* rdfDescriptor;
  6239. bool embedded;
  6240. bool fileBrowserOpen;
  6241. const char* fileNeededForURI;
  6242. CarlaPluginUI* window;
  6243. UI()
  6244. : type(TYPE_NULL),
  6245. handle(nullptr),
  6246. widget(nullptr),
  6247. descriptor(nullptr),
  6248. rdfDescriptor(nullptr),
  6249. embedded(false),
  6250. fileBrowserOpen(false),
  6251. fileNeededForURI(nullptr),
  6252. window(nullptr) {}
  6253. ~UI()
  6254. {
  6255. CARLA_SAFE_ASSERT(handle == nullptr);
  6256. CARLA_SAFE_ASSERT(widget == nullptr);
  6257. CARLA_SAFE_ASSERT(descriptor == nullptr);
  6258. CARLA_SAFE_ASSERT(rdfDescriptor == nullptr);
  6259. CARLA_SAFE_ASSERT(! fileBrowserOpen);
  6260. CARLA_SAFE_ASSERT(fileNeededForURI == nullptr);
  6261. CARLA_SAFE_ASSERT(window == nullptr);
  6262. }
  6263. CARLA_DECLARE_NON_COPYABLE(UI);
  6264. } fUI;
  6265. // -------------------------------------------------------------------
  6266. // Event Feature
  6267. static uint32_t carla_lv2_event_ref(LV2_Event_Callback_Data callback_data, LV2_Event* event)
  6268. {
  6269. CARLA_SAFE_ASSERT_RETURN(callback_data != nullptr, 0);
  6270. CARLA_SAFE_ASSERT_RETURN(event != nullptr, 0);
  6271. carla_debug("carla_lv2_event_ref(%p, %p)", callback_data, event);
  6272. return 0;
  6273. }
  6274. static uint32_t carla_lv2_event_unref(LV2_Event_Callback_Data callback_data, LV2_Event* event)
  6275. {
  6276. CARLA_SAFE_ASSERT_RETURN(callback_data != nullptr, 0);
  6277. CARLA_SAFE_ASSERT_RETURN(event != nullptr, 0);
  6278. carla_debug("carla_lv2_event_unref(%p, %p)", callback_data, event);
  6279. return 0;
  6280. }
  6281. // -------------------------------------------------------------------
  6282. // Logs Feature
  6283. static int carla_lv2_log_printf(LV2_Log_Handle handle, LV2_URID type, const char* fmt, ...)
  6284. {
  6285. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, 0);
  6286. CARLA_SAFE_ASSERT_RETURN(type != kUridNull, 0);
  6287. CARLA_SAFE_ASSERT_RETURN(fmt != nullptr, 0);
  6288. #ifndef DEBUG
  6289. if (type == kUridLogTrace)
  6290. return 0;
  6291. #endif
  6292. va_list args;
  6293. va_start(args, fmt);
  6294. const int ret(carla_lv2_log_vprintf(handle, type, fmt, args));
  6295. va_end(args);
  6296. return ret;
  6297. }
  6298. static int carla_lv2_log_vprintf(LV2_Log_Handle handle, LV2_URID type, const char* fmt, va_list ap)
  6299. {
  6300. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, 0);
  6301. CARLA_SAFE_ASSERT_RETURN(type != kUridNull, 0);
  6302. CARLA_SAFE_ASSERT_RETURN(fmt != nullptr, 0);
  6303. int ret = 0;
  6304. switch (type)
  6305. {
  6306. case kUridLogError:
  6307. std::fprintf(stderr, "\x1b[31m");
  6308. ret = std::vfprintf(stderr, fmt, ap);
  6309. std::fprintf(stderr, "\x1b[0m");
  6310. break;
  6311. case kUridLogNote:
  6312. ret = std::vfprintf(stdout, fmt, ap);
  6313. break;
  6314. case kUridLogTrace:
  6315. #ifdef DEBUG
  6316. std::fprintf(stdout, "\x1b[30;1m");
  6317. ret = std::vfprintf(stdout, fmt, ap);
  6318. std::fprintf(stdout, "\x1b[0m");
  6319. #endif
  6320. break;
  6321. case kUridLogWarning:
  6322. ret = std::vfprintf(stderr, fmt, ap);
  6323. break;
  6324. default:
  6325. break;
  6326. }
  6327. return ret;
  6328. }
  6329. // -------------------------------------------------------------------
  6330. // Programs Feature
  6331. static void carla_lv2_program_changed(LV2_Programs_Handle handle, int32_t index)
  6332. {
  6333. CARLA_SAFE_ASSERT_RETURN(handle != nullptr,);
  6334. carla_debug("carla_lv2_program_changed(%p, %i)", handle, index);
  6335. ((CarlaPluginLV2*)handle)->handleProgramChanged(index);
  6336. }
  6337. // -------------------------------------------------------------------
  6338. // Resize Port Feature
  6339. static LV2_Resize_Port_Status carla_lv2_resize_port(LV2_Resize_Port_Feature_Data data, uint32_t index, size_t size)
  6340. {
  6341. CARLA_SAFE_ASSERT_RETURN(data != nullptr, LV2_RESIZE_PORT_ERR_UNKNOWN);
  6342. carla_debug("carla_lv2_program_changed(%p, %i, " P_SIZE ")", data, index, size);
  6343. return ((CarlaPluginLV2*)data)->handleResizePort(index, size);
  6344. }
  6345. // -------------------------------------------------------------------
  6346. // State Feature
  6347. static void carla_lv2_state_free_path(LV2_State_Free_Path_Handle handle, char* const path)
  6348. {
  6349. CARLA_SAFE_ASSERT_RETURN(handle != nullptr,);
  6350. carla_debug("carla_lv2_state_free_path(%p, \"%s\")", handle, path);
  6351. std::free(path);
  6352. }
  6353. static char* carla_lv2_state_make_path_real(LV2_State_Make_Path_Handle handle, const char* path)
  6354. {
  6355. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
  6356. CARLA_SAFE_ASSERT_RETURN(path != nullptr, nullptr);
  6357. carla_debug("carla_lv2_state_make_path_real(%p, \"%s\")", handle, path);
  6358. // allow empty paths to mean "current dir"
  6359. if (path[0] == '\0')
  6360. path = ".";
  6361. const File file(((CarlaPluginLV2*)handle)->handleStateMapToAbsolutePath(true, false, false, path));
  6362. return file.isNotNull() ? strdup(file.getFullPathName().toRawUTF8()) : nullptr;
  6363. }
  6364. static char* carla_lv2_state_make_path_tmp(LV2_State_Make_Path_Handle handle, const char* path)
  6365. {
  6366. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
  6367. CARLA_SAFE_ASSERT_RETURN(path != nullptr, nullptr);
  6368. carla_debug("carla_lv2_state_make_path_tmp(%p, \"%s\")", handle, path);
  6369. // allow empty paths to mean "current dir"
  6370. if (path[0] == '\0')
  6371. path = ".";
  6372. const File file(((CarlaPluginLV2*)handle)->handleStateMapToAbsolutePath(true, false, true, path));
  6373. return file.isNotNull() ? strdup(file.getFullPathName().toRawUTF8()) : nullptr;
  6374. }
  6375. static char* carla_lv2_state_map_to_abstract_path_real(LV2_State_Map_Path_Handle handle, const char* const absolute_path)
  6376. {
  6377. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
  6378. CARLA_SAFE_ASSERT_RETURN(absolute_path != nullptr, nullptr);
  6379. carla_debug("carla_lv2_state_map_to_abstract_path_real(%p, \"%s\")", handle, absolute_path);
  6380. // handle invalid empty paths the same way as lilv
  6381. if (absolute_path[0] != '\0')
  6382. return strdup("");
  6383. return ((CarlaPluginLV2*)handle)->handleStateMapToAbstractPath(false, absolute_path);
  6384. }
  6385. static char* carla_lv2_state_map_to_abstract_path_tmp(LV2_State_Map_Path_Handle handle, const char* const absolute_path)
  6386. {
  6387. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
  6388. CARLA_SAFE_ASSERT_RETURN(absolute_path != nullptr, nullptr);
  6389. carla_debug("carla_lv2_state_map_to_abstract_path_tmp(%p, \"%s\")", handle, absolute_path);
  6390. // handle invalid empty paths the same way as lilv
  6391. if (absolute_path[0] != '\0')
  6392. return strdup("");
  6393. return ((CarlaPluginLV2*)handle)->handleStateMapToAbstractPath(true, absolute_path);
  6394. }
  6395. static char* carla_lv2_state_map_to_absolute_path_real(LV2_State_Map_Path_Handle handle, const char* abstract_path)
  6396. {
  6397. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
  6398. CARLA_SAFE_ASSERT_RETURN(abstract_path != nullptr, nullptr);
  6399. carla_debug("carla_lv2_state_map_to_absolute_path_real(%p, \"%s\")", handle, abstract_path);
  6400. // allow empty paths to mean "current dir"
  6401. if (abstract_path[0] == '\0')
  6402. abstract_path = ".";
  6403. const File file(((CarlaPluginLV2*)handle)->handleStateMapToAbsolutePath(true, true, false, abstract_path));
  6404. return file.isNotNull() ? strdup(file.getFullPathName().toRawUTF8()) : nullptr;
  6405. }
  6406. static char* carla_lv2_state_map_to_absolute_path_tmp(LV2_State_Map_Path_Handle handle, const char* abstract_path)
  6407. {
  6408. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
  6409. CARLA_SAFE_ASSERT_RETURN(abstract_path != nullptr, nullptr);
  6410. carla_debug("carla_lv2_state_map_to_absolute_path_tmp(%p, \"%s\")", handle, abstract_path);
  6411. // allow empty paths to mean "current dir"
  6412. if (abstract_path[0] == '\0')
  6413. abstract_path = ".";
  6414. const File file(((CarlaPluginLV2*)handle)->handleStateMapToAbsolutePath(true, true, true, abstract_path));
  6415. return file.isNotNull() ? strdup(file.getFullPathName().toRawUTF8()) : nullptr;
  6416. }
  6417. static LV2_State_Status carla_lv2_state_store(LV2_State_Handle handle, uint32_t key, const void* value, size_t size, uint32_t type, uint32_t flags)
  6418. {
  6419. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, LV2_STATE_ERR_UNKNOWN);
  6420. carla_debug("carla_lv2_state_store(%p, %i, %p, " P_SIZE ", %i, %i)", handle, key, value, size, type, flags);
  6421. return ((CarlaPluginLV2*)handle)->handleStateStore(key, value, size, type, flags);
  6422. }
  6423. static const void* carla_lv2_state_retrieve(LV2_State_Handle handle, uint32_t key, size_t* size, uint32_t* type, uint32_t* flags)
  6424. {
  6425. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
  6426. carla_debug("carla_lv2_state_retrieve(%p, %i, %p, %p, %p)", handle, key, size, type, flags);
  6427. return ((CarlaPluginLV2*)handle)->handleStateRetrieve(key, size, type, flags);
  6428. }
  6429. // -------------------------------------------------------------------
  6430. // URI-Map Feature
  6431. static uint32_t carla_lv2_uri_to_id(LV2_URI_Map_Callback_Data data, const char* map, const char* uri)
  6432. {
  6433. carla_debug("carla_lv2_uri_to_id(%p, \"%s\", \"%s\")", data, map, uri);
  6434. return carla_lv2_urid_map((LV2_URID_Map_Handle*)data, uri);
  6435. // unused
  6436. (void)map;
  6437. }
  6438. // -------------------------------------------------------------------
  6439. // URID Feature
  6440. static LV2_URID carla_lv2_urid_map(LV2_URID_Map_Handle handle, const char* uri)
  6441. {
  6442. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, kUridNull);
  6443. CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0', kUridNull);
  6444. carla_debug("carla_lv2_urid_map(%p, \"%s\")", handle, uri);
  6445. // Atom types
  6446. if (std::strcmp(uri, LV2_ATOM__Blank) == 0)
  6447. return kUridAtomBlank;
  6448. if (std::strcmp(uri, LV2_ATOM__Bool) == 0)
  6449. return kUridAtomBool;
  6450. if (std::strcmp(uri, LV2_ATOM__Chunk) == 0)
  6451. return kUridAtomChunk;
  6452. if (std::strcmp(uri, LV2_ATOM__Double) == 0)
  6453. return kUridAtomDouble;
  6454. if (std::strcmp(uri, LV2_ATOM__Event) == 0)
  6455. return kUridAtomEvent;
  6456. if (std::strcmp(uri, LV2_ATOM__Float) == 0)
  6457. return kUridAtomFloat;
  6458. if (std::strcmp(uri, LV2_ATOM__Int) == 0)
  6459. return kUridAtomInt;
  6460. if (std::strcmp(uri, LV2_ATOM__Literal) == 0)
  6461. return kUridAtomLiteral;
  6462. if (std::strcmp(uri, LV2_ATOM__Long) == 0)
  6463. return kUridAtomLong;
  6464. if (std::strcmp(uri, LV2_ATOM__Number) == 0)
  6465. return kUridAtomNumber;
  6466. if (std::strcmp(uri, LV2_ATOM__Object) == 0)
  6467. return kUridAtomObject;
  6468. if (std::strcmp(uri, LV2_ATOM__Path) == 0)
  6469. return kUridAtomPath;
  6470. if (std::strcmp(uri, LV2_ATOM__Property) == 0)
  6471. return kUridAtomProperty;
  6472. if (std::strcmp(uri, LV2_ATOM__Resource) == 0)
  6473. return kUridAtomResource;
  6474. if (std::strcmp(uri, LV2_ATOM__Sequence) == 0)
  6475. return kUridAtomSequence;
  6476. if (std::strcmp(uri, LV2_ATOM__Sound) == 0)
  6477. return kUridAtomSound;
  6478. if (std::strcmp(uri, LV2_ATOM__String) == 0)
  6479. return kUridAtomString;
  6480. if (std::strcmp(uri, LV2_ATOM__Tuple) == 0)
  6481. return kUridAtomTuple;
  6482. if (std::strcmp(uri, LV2_ATOM__URI) == 0)
  6483. return kUridAtomURI;
  6484. if (std::strcmp(uri, LV2_ATOM__URID) == 0)
  6485. return kUridAtomURID;
  6486. if (std::strcmp(uri, LV2_ATOM__Vector) == 0)
  6487. return kUridAtomVector;
  6488. if (std::strcmp(uri, LV2_ATOM__atomTransfer) == 0)
  6489. return kUridAtomTransferAtom;
  6490. if (std::strcmp(uri, LV2_ATOM__eventTransfer) == 0)
  6491. return kUridAtomTransferEvent;
  6492. // BufSize types
  6493. if (std::strcmp(uri, LV2_BUF_SIZE__maxBlockLength) == 0)
  6494. return kUridBufMaxLength;
  6495. if (std::strcmp(uri, LV2_BUF_SIZE__minBlockLength) == 0)
  6496. return kUridBufMinLength;
  6497. if (std::strcmp(uri, LV2_BUF_SIZE__nominalBlockLength) == 0)
  6498. return kUridBufNominalLength;
  6499. if (std::strcmp(uri, LV2_BUF_SIZE__sequenceSize) == 0)
  6500. return kUridBufSequenceSize;
  6501. // Log types
  6502. if (std::strcmp(uri, LV2_LOG__Error) == 0)
  6503. return kUridLogError;
  6504. if (std::strcmp(uri, LV2_LOG__Note) == 0)
  6505. return kUridLogNote;
  6506. if (std::strcmp(uri, LV2_LOG__Trace) == 0)
  6507. return kUridLogTrace;
  6508. if (std::strcmp(uri, LV2_LOG__Warning) == 0)
  6509. return kUridLogWarning;
  6510. // Patch types
  6511. if (std::strcmp(uri, LV2_PATCH__Set) == 0)
  6512. return kUridPatchSet;
  6513. if (std::strcmp(uri, LV2_PATCH__property) == 0)
  6514. return kUridPatchProperty;
  6515. if (std::strcmp(uri, LV2_PATCH__subject) == 0)
  6516. return kUridPatchSubject;
  6517. if (std::strcmp(uri, LV2_PATCH__value) == 0)
  6518. return kUridPatchValue;
  6519. // Time types
  6520. if (std::strcmp(uri, LV2_TIME__Position) == 0)
  6521. return kUridTimePosition;
  6522. if (std::strcmp(uri, LV2_TIME__bar) == 0)
  6523. return kUridTimeBar;
  6524. if (std::strcmp(uri, LV2_TIME__barBeat) == 0)
  6525. return kUridTimeBarBeat;
  6526. if (std::strcmp(uri, LV2_TIME__beat) == 0)
  6527. return kUridTimeBeat;
  6528. if (std::strcmp(uri, LV2_TIME__beatUnit) == 0)
  6529. return kUridTimeBeatUnit;
  6530. if (std::strcmp(uri, LV2_TIME__beatsPerBar) == 0)
  6531. return kUridTimeBeatsPerBar;
  6532. if (std::strcmp(uri, LV2_TIME__beatsPerMinute) == 0)
  6533. return kUridTimeBeatsPerMinute;
  6534. if (std::strcmp(uri, LV2_TIME__frame) == 0)
  6535. return kUridTimeFrame;
  6536. if (std::strcmp(uri, LV2_TIME__framesPerSecond) == 0)
  6537. return kUridTimeFramesPerSecond;
  6538. if (std::strcmp(uri, LV2_TIME__speed) == 0)
  6539. return kUridTimeSpeed;
  6540. if (std::strcmp(uri, LV2_KXSTUDIO_PROPERTIES__TimePositionTicksPerBeat) == 0)
  6541. return kUridTimeTicksPerBeat;
  6542. // Others
  6543. if (std::strcmp(uri, LV2_MIDI__MidiEvent) == 0)
  6544. return kUridMidiEvent;
  6545. if (std::strcmp(uri, LV2_PARAMETERS__sampleRate) == 0)
  6546. return kUridParamSampleRate;
  6547. if (std::strcmp(uri, LV2_UI__backgroundColor) == 0)
  6548. return kUridBackgroundColor;
  6549. if (std::strcmp(uri, LV2_UI__foregroundColor) == 0)
  6550. return kUridForegroundColor;
  6551. #ifndef CARLA_OS_MAC
  6552. if (std::strcmp(uri, LV2_UI__scaleFactor) == 0)
  6553. return kUridScaleFactor;
  6554. #endif
  6555. if (std::strcmp(uri, LV2_UI__windowTitle) == 0)
  6556. return kUridWindowTitle;
  6557. // Custom Carla types
  6558. if (std::strcmp(uri, URI_CARLA_ATOM_WORKER_IN) == 0)
  6559. return kUridCarlaAtomWorkerIn;
  6560. if (std::strcmp(uri, URI_CARLA_ATOM_WORKER_RESP) == 0)
  6561. return kUridCarlaAtomWorkerResp;
  6562. if (std::strcmp(uri, URI_CARLA_PARAMETER_CHANGE) == 0)
  6563. return kUridCarlaParameterChange;
  6564. if (std::strcmp(uri, LV2_KXSTUDIO_PROPERTIES__TransientWindowId) == 0)
  6565. return kUridCarlaTransientWindowId;
  6566. // Custom plugin types
  6567. return ((CarlaPluginLV2*)handle)->getCustomURID(uri);
  6568. }
  6569. static const char* carla_lv2_urid_unmap(LV2_URID_Map_Handle handle, LV2_URID urid)
  6570. {
  6571. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
  6572. CARLA_SAFE_ASSERT_RETURN(urid != kUridNull, nullptr);
  6573. carla_debug("carla_lv2_urid_unmap(%p, %i)", handle, urid);
  6574. switch (urid)
  6575. {
  6576. // Atom types
  6577. case kUridAtomBlank:
  6578. return LV2_ATOM__Blank;
  6579. case kUridAtomBool:
  6580. return LV2_ATOM__Bool;
  6581. case kUridAtomChunk:
  6582. return LV2_ATOM__Chunk;
  6583. case kUridAtomDouble:
  6584. return LV2_ATOM__Double;
  6585. case kUridAtomEvent:
  6586. return LV2_ATOM__Event;
  6587. case kUridAtomFloat:
  6588. return LV2_ATOM__Float;
  6589. case kUridAtomInt:
  6590. return LV2_ATOM__Int;
  6591. case kUridAtomLiteral:
  6592. return LV2_ATOM__Literal;
  6593. case kUridAtomLong:
  6594. return LV2_ATOM__Long;
  6595. case kUridAtomNumber:
  6596. return LV2_ATOM__Number;
  6597. case kUridAtomObject:
  6598. return LV2_ATOM__Object;
  6599. case kUridAtomPath:
  6600. return LV2_ATOM__Path;
  6601. case kUridAtomProperty:
  6602. return LV2_ATOM__Property;
  6603. case kUridAtomResource:
  6604. return LV2_ATOM__Resource;
  6605. case kUridAtomSequence:
  6606. return LV2_ATOM__Sequence;
  6607. case kUridAtomSound:
  6608. return LV2_ATOM__Sound;
  6609. case kUridAtomString:
  6610. return LV2_ATOM__String;
  6611. case kUridAtomTuple:
  6612. return LV2_ATOM__Tuple;
  6613. case kUridAtomURI:
  6614. return LV2_ATOM__URI;
  6615. case kUridAtomURID:
  6616. return LV2_ATOM__URID;
  6617. case kUridAtomVector:
  6618. return LV2_ATOM__Vector;
  6619. case kUridAtomTransferAtom:
  6620. return LV2_ATOM__atomTransfer;
  6621. case kUridAtomTransferEvent:
  6622. return LV2_ATOM__eventTransfer;
  6623. // BufSize types
  6624. case kUridBufMaxLength:
  6625. return LV2_BUF_SIZE__maxBlockLength;
  6626. case kUridBufMinLength:
  6627. return LV2_BUF_SIZE__minBlockLength;
  6628. case kUridBufNominalLength:
  6629. return LV2_BUF_SIZE__nominalBlockLength;
  6630. case kUridBufSequenceSize:
  6631. return LV2_BUF_SIZE__sequenceSize;
  6632. // Log types
  6633. case kUridLogError:
  6634. return LV2_LOG__Error;
  6635. case kUridLogNote:
  6636. return LV2_LOG__Note;
  6637. case kUridLogTrace:
  6638. return LV2_LOG__Trace;
  6639. case kUridLogWarning:
  6640. return LV2_LOG__Warning;
  6641. // Patch types
  6642. case kUridPatchSet:
  6643. return LV2_PATCH__Set;
  6644. case kUridPatchProperty:
  6645. return LV2_PATCH__property;
  6646. case kUridPatchSubject:
  6647. return LV2_PATCH__subject;
  6648. case kUridPatchValue:
  6649. return LV2_PATCH__value;
  6650. // Time types
  6651. case kUridTimePosition:
  6652. return LV2_TIME__Position;
  6653. case kUridTimeBar:
  6654. return LV2_TIME__bar;
  6655. case kUridTimeBarBeat:
  6656. return LV2_TIME__barBeat;
  6657. case kUridTimeBeat:
  6658. return LV2_TIME__beat;
  6659. case kUridTimeBeatUnit:
  6660. return LV2_TIME__beatUnit;
  6661. case kUridTimeBeatsPerBar:
  6662. return LV2_TIME__beatsPerBar;
  6663. case kUridTimeBeatsPerMinute:
  6664. return LV2_TIME__beatsPerMinute;
  6665. case kUridTimeFrame:
  6666. return LV2_TIME__frame;
  6667. case kUridTimeFramesPerSecond:
  6668. return LV2_TIME__framesPerSecond;
  6669. case kUridTimeSpeed:
  6670. return LV2_TIME__speed;
  6671. case kUridTimeTicksPerBeat:
  6672. return LV2_KXSTUDIO_PROPERTIES__TimePositionTicksPerBeat;
  6673. // Others
  6674. case kUridMidiEvent:
  6675. return LV2_MIDI__MidiEvent;
  6676. case kUridParamSampleRate:
  6677. return LV2_PARAMETERS__sampleRate;
  6678. case kUridBackgroundColor:
  6679. return LV2_UI__backgroundColor;
  6680. case kUridForegroundColor:
  6681. return LV2_UI__foregroundColor;
  6682. #ifndef CARLA_OS_MAC
  6683. case kUridScaleFactor:
  6684. return LV2_UI__scaleFactor;
  6685. #endif
  6686. case kUridWindowTitle:
  6687. return LV2_UI__windowTitle;
  6688. // Custom Carla types
  6689. case kUridCarlaAtomWorkerIn:
  6690. return URI_CARLA_ATOM_WORKER_IN;
  6691. case kUridCarlaAtomWorkerResp:
  6692. return URI_CARLA_ATOM_WORKER_RESP;
  6693. case kUridCarlaParameterChange:
  6694. return URI_CARLA_PARAMETER_CHANGE;
  6695. case kUridCarlaTransientWindowId:
  6696. return LV2_KXSTUDIO_PROPERTIES__TransientWindowId;
  6697. }
  6698. // Custom plugin types
  6699. return ((CarlaPluginLV2*)handle)->getCustomURIDString(urid);
  6700. }
  6701. // -------------------------------------------------------------------
  6702. // Worker Feature
  6703. static LV2_Worker_Status carla_lv2_worker_schedule(LV2_Worker_Schedule_Handle handle, uint32_t size, const void* data)
  6704. {
  6705. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, LV2_WORKER_ERR_UNKNOWN);
  6706. carla_debug("carla_lv2_worker_schedule(%p, %i, %p)", handle, size, data);
  6707. return ((CarlaPluginLV2*)handle)->handleWorkerSchedule(size, data);
  6708. }
  6709. static LV2_Worker_Status carla_lv2_worker_respond(LV2_Worker_Respond_Handle handle, uint32_t size, const void* data)
  6710. {
  6711. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, LV2_WORKER_ERR_UNKNOWN);
  6712. carla_debug("carla_lv2_worker_respond(%p, %i, %p)", handle, size, data);
  6713. return ((CarlaPluginLV2*)handle)->handleWorkerRespond(size, data);
  6714. }
  6715. // -------------------------------------------------------------------
  6716. // Inline Display Feature
  6717. static void carla_lv2_inline_display_queue_draw(LV2_Inline_Display_Handle handle)
  6718. {
  6719. CARLA_SAFE_ASSERT_RETURN(handle != nullptr,);
  6720. // carla_debug("carla_lv2_inline_display_queue_draw(%p)", handle);
  6721. ((CarlaPluginLV2*)handle)->handleInlineDisplayQueueRedraw();
  6722. }
  6723. // -------------------------------------------------------------------
  6724. // Midnam Feature
  6725. static void carla_lv2_midnam_update(LV2_Midnam_Handle handle)
  6726. {
  6727. CARLA_SAFE_ASSERT_RETURN(handle != nullptr,);
  6728. carla_stdout("carla_lv2_midnam_update(%p)", handle);
  6729. ((CarlaPluginLV2*)handle)->handleMidnamUpdate();
  6730. }
  6731. // -------------------------------------------------------------------
  6732. // External UI Feature
  6733. static void carla_lv2_external_ui_closed(LV2UI_Controller controller)
  6734. {
  6735. CARLA_SAFE_ASSERT_RETURN(controller != nullptr,);
  6736. carla_debug("carla_lv2_external_ui_closed(%p)", controller);
  6737. ((CarlaPluginLV2*)controller)->handleExternalUIClosed();
  6738. }
  6739. // -------------------------------------------------------------------
  6740. // UI Port-Map Feature
  6741. static uint32_t carla_lv2_ui_port_map(LV2UI_Feature_Handle handle, const char* symbol)
  6742. {
  6743. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, LV2UI_INVALID_PORT_INDEX);
  6744. carla_debug("carla_lv2_ui_port_map(%p, \"%s\")", handle, symbol);
  6745. return ((CarlaPluginLV2*)handle)->handleUIPortMap(symbol);
  6746. }
  6747. // ----------------------------------------------------------------------------------------------------------------
  6748. // UI Request Parameter Feature
  6749. static LV2UI_Request_Value_Status carla_lv2_ui_request_value(LV2UI_Feature_Handle handle,
  6750. LV2_URID key,
  6751. LV2_URID type,
  6752. const LV2_Feature* const* features)
  6753. {
  6754. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, LV2UI_REQUEST_VALUE_ERR_UNKNOWN);
  6755. carla_debug("carla_lv2_ui_request_value(%p, %u, %u, %p)", handle, key, type, features);
  6756. return ((CarlaPluginLV2*)handle)->handleUIRequestValue(key, type, features);
  6757. }
  6758. // -------------------------------------------------------------------
  6759. // UI Resize Feature
  6760. static int carla_lv2_ui_resize(LV2UI_Feature_Handle handle, int width, int height)
  6761. {
  6762. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, 1);
  6763. carla_debug("carla_lv2_ui_resize(%p, %i, %i)", handle, width, height);
  6764. return ((CarlaPluginLV2*)handle)->handleUIResize(width, height);
  6765. }
  6766. // -------------------------------------------------------------------
  6767. // UI Touch Feature
  6768. static void carla_lv2_ui_touch(LV2UI_Feature_Handle handle, uint32_t port_index, bool touch)
  6769. {
  6770. CARLA_SAFE_ASSERT_RETURN(handle != nullptr,);
  6771. carla_debug("carla_lv2_ui_touch(%p, %u, %s)", handle, port_index, bool2str(touch));
  6772. ((CarlaPluginLV2*)handle)->handleUITouch(port_index, touch);
  6773. }
  6774. // -------------------------------------------------------------------
  6775. // UI Extension
  6776. static void carla_lv2_ui_write_function(LV2UI_Controller controller, uint32_t port_index, uint32_t buffer_size, uint32_t format, const void* buffer)
  6777. {
  6778. CARLA_SAFE_ASSERT_RETURN(controller != nullptr,);
  6779. carla_debug("carla_lv2_ui_write_function(%p, %i, %i, %i, %p)", controller, port_index, buffer_size, format, buffer);
  6780. ((CarlaPluginLV2*)controller)->handleUIWrite(port_index, buffer_size, format, buffer);
  6781. }
  6782. // -------------------------------------------------------------------
  6783. // Lilv State
  6784. static void carla_lilv_set_port_value(const char* port_symbol, void* user_data, const void* value, uint32_t size, uint32_t type)
  6785. {
  6786. CARLA_SAFE_ASSERT_RETURN(user_data != nullptr,);
  6787. carla_debug("carla_lilv_set_port_value(\"%s\", %p, %p, %i, %i", port_symbol, user_data, value, size, type);
  6788. ((CarlaPluginLV2*)user_data)->handleLilvSetPortValue(port_symbol, value, size, type);
  6789. }
  6790. // -------------------------------------------------------------------
  6791. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginLV2)
  6792. };
  6793. // -------------------------------------------------------------------------------------------------------------------
  6794. #ifndef LV2_UIS_ONLY_INPROCESS
  6795. bool CarlaPipeServerLV2::msgReceived(const char* const msg) noexcept
  6796. {
  6797. if (std::strcmp(msg, "exiting") == 0)
  6798. {
  6799. closePipeServer();
  6800. fUiState = UiHide;
  6801. return true;
  6802. }
  6803. if (std::strcmp(msg, "control") == 0)
  6804. {
  6805. uint32_t index;
  6806. float value;
  6807. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(index), true);
  6808. CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
  6809. try {
  6810. kPlugin->handleUIWrite(index, sizeof(float), kUridNull, &value);
  6811. } CARLA_SAFE_EXCEPTION("magReceived control");
  6812. return true;
  6813. }
  6814. if (std::strcmp(msg, "pcontrol") == 0)
  6815. {
  6816. const char* uri;
  6817. float value;
  6818. CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(uri, true), true);
  6819. CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
  6820. try {
  6821. kPlugin->handleUIBridgeParameter(uri, value);
  6822. } CARLA_SAFE_EXCEPTION("magReceived pcontrol");
  6823. return true;
  6824. }
  6825. if (std::strcmp(msg, "atom") == 0)
  6826. {
  6827. uint32_t index, atomTotalSize, base64Size;
  6828. const char* base64atom;
  6829. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(index), true);
  6830. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(atomTotalSize), true);
  6831. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(base64Size), true);
  6832. CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(base64atom, false, base64Size), true);
  6833. std::vector<uint8_t> chunk(carla_getChunkFromBase64String(base64atom));
  6834. CARLA_SAFE_ASSERT_UINT2_RETURN(chunk.size() >= sizeof(LV2_Atom), chunk.size(), sizeof(LV2_Atom), true);
  6835. #ifdef CARLA_PROPER_CPP11_SUPPORT
  6836. const LV2_Atom* const atom((const LV2_Atom*)chunk.data());
  6837. #else
  6838. const LV2_Atom* const atom((const LV2_Atom*)&chunk.front());
  6839. #endif
  6840. CARLA_SAFE_ASSERT_RETURN(lv2_atom_total_size(atom) == chunk.size(), true);
  6841. try {
  6842. kPlugin->handleUIWrite(index, lv2_atom_total_size(atom), kUridAtomTransferEvent, atom);
  6843. } CARLA_SAFE_EXCEPTION("magReceived atom");
  6844. return true;
  6845. }
  6846. if (std::strcmp(msg, "program") == 0)
  6847. {
  6848. uint32_t index;
  6849. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(index), true);
  6850. try {
  6851. kPlugin->setMidiProgram(static_cast<int32_t>(index), false, true, true, false);
  6852. } CARLA_SAFE_EXCEPTION("msgReceived program");
  6853. return true;
  6854. }
  6855. if (std::strcmp(msg, "urid") == 0)
  6856. {
  6857. uint32_t urid, size;
  6858. const char* uri;
  6859. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(urid), true);
  6860. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(size), true);
  6861. CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(uri, false, size), true);
  6862. if (urid != 0)
  6863. {
  6864. try {
  6865. kPlugin->handleUridMap(urid, uri);
  6866. } CARLA_SAFE_EXCEPTION("msgReceived urid");
  6867. }
  6868. return true;
  6869. }
  6870. if (std::strcmp(msg, "reloadprograms") == 0)
  6871. {
  6872. int32_t index;
  6873. CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(index), true);
  6874. try {
  6875. kPlugin->handleProgramChanged(index);
  6876. } CARLA_SAFE_EXCEPTION("handleProgramChanged");
  6877. return true;
  6878. }
  6879. if (std::strcmp(msg, "requestvalue") == 0)
  6880. {
  6881. uint32_t key, type;
  6882. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(key), true);
  6883. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(type), true);
  6884. if (key != 0)
  6885. {
  6886. try {
  6887. kPlugin->handleUIRequestValue(key, type, nullptr);
  6888. } CARLA_SAFE_EXCEPTION("msgReceived requestvalue");
  6889. }
  6890. return true;
  6891. }
  6892. return false;
  6893. }
  6894. #endif
  6895. // -------------------------------------------------------------------------------------------------------------------
  6896. CarlaPluginPtr CarlaPlugin::newLV2(const Initializer& init)
  6897. {
  6898. carla_debug("CarlaPlugin::newLV2({%p, \"%s\", \"%s\"})", init.engine, init.name, init.label);
  6899. std::shared_ptr<CarlaPluginLV2> plugin(new CarlaPluginLV2(init.engine, init.id));
  6900. const char* needsArchBridge = nullptr;
  6901. if (plugin->init(plugin, init.name, init.label, init.options, needsArchBridge))
  6902. return plugin;
  6903. #ifndef CARLA_OS_WASM
  6904. if (needsArchBridge != nullptr)
  6905. {
  6906. CarlaString bridgeBinary(init.engine->getOptions().binaryDir);
  6907. bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-native";
  6908. return CarlaPlugin::newBridge(init, BINARY_NATIVE, PLUGIN_LV2, needsArchBridge, bridgeBinary);
  6909. }
  6910. #endif
  6911. return nullptr;
  6912. }
  6913. // used in CarlaStandalone.cpp
  6914. const void* carla_render_inline_display_lv2(const CarlaPluginPtr& plugin, uint32_t width, uint32_t height);
  6915. const void* carla_render_inline_display_lv2(const CarlaPluginPtr& plugin, uint32_t width, uint32_t height)
  6916. {
  6917. const std::shared_ptr<CarlaPluginLV2>& lv2Plugin((const std::shared_ptr<CarlaPluginLV2>&)plugin);
  6918. return lv2Plugin->renderInlineDisplay(width, height);
  6919. }
  6920. // -------------------------------------------------------------------------------------------------------------------
  6921. CARLA_BACKEND_END_NAMESPACE