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.

carla-lv2.cpp 57KB

10 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
10 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
10 years ago
10 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714
  1. /*
  2. * Carla Native Plugins
  3. * Copyright (C) 2013-2014 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. #define CARLA_NATIVE_PLUGIN_LV2
  18. #include "carla-base.cpp"
  19. #include "CarlaLv2Utils.hpp"
  20. #include "CarlaMathUtils.hpp"
  21. #include "CarlaString.hpp"
  22. #include "juce_audio_basics.h"
  23. #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN)
  24. # include "juce_gui_basics.h"
  25. #else
  26. namespace juce {
  27. # include "juce_events/messages/juce_Initialisation.h"
  28. } // namespace juce
  29. #endif
  30. using juce::FloatVectorOperations;
  31. using juce::ScopedJuceInitialiser_GUI;
  32. using juce::SharedResourcePointer;
  33. // -----------------------------------------------------------------------
  34. // -Weffc++ compat ext widget
  35. extern "C" {
  36. typedef struct _LV2_External_UI_Widget_Compat {
  37. void (*run )(struct _LV2_External_UI_Widget_Compat*);
  38. void (*show)(struct _LV2_External_UI_Widget_Compat*);
  39. void (*hide)(struct _LV2_External_UI_Widget_Compat*);
  40. _LV2_External_UI_Widget_Compat() noexcept
  41. : run(nullptr), show(nullptr), hide(nullptr) {}
  42. } LV2_External_UI_Widget_Compat;
  43. }
  44. // -----------------------------------------------------------------------
  45. // LV2 descriptor functions
  46. #if defined(__clang__)
  47. # pragma clang diagnostic push
  48. # pragma clang diagnostic ignored "-Weffc++"
  49. #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
  50. # pragma GCC diagnostic push
  51. # pragma GCC diagnostic ignored "-Weffc++"
  52. #endif
  53. class NativePlugin : public LV2_External_UI_Widget_Compat
  54. {
  55. #if defined(__clang__)
  56. # pragma clang diagnostic pop
  57. #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
  58. # pragma GCC diagnostic pop
  59. #endif
  60. public:
  61. static const uint32_t kMaxMidiEvents = 512;
  62. NativePlugin(const NativePluginDescriptor* const desc, const double sampleRate, const char* const bundlePath, const LV2_Feature* const* features)
  63. : fHandle(nullptr),
  64. fHost(),
  65. fDescriptor(desc),
  66. #ifdef CARLA_PROPER_CPP11_SUPPORT
  67. fProgramDesc({0, 0, nullptr}),
  68. #endif
  69. fMidiEventCount(0),
  70. fTimeInfo(),
  71. fLastTimeSpeed(0.0),
  72. fIsProcessing(false),
  73. fBufferSize(0),
  74. fSampleRate(sampleRate),
  75. fUridMap(nullptr),
  76. fURIs(),
  77. fUI(),
  78. fPorts(),
  79. sJuceInitialiser()
  80. {
  81. run = extui_run;
  82. show = extui_show;
  83. hide = extui_hide;
  84. CarlaString resourceDir(bundlePath);
  85. #ifdef CARLA_OS_WIN
  86. resourceDir += "\\resources\\";
  87. #else
  88. resourceDir += "/resources/";
  89. #endif
  90. fHost.handle = this;
  91. fHost.resourceDir = resourceDir.dup();
  92. fHost.uiName = nullptr;
  93. fHost.uiParentId = 0;
  94. fHost.get_buffer_size = host_get_buffer_size;
  95. fHost.get_sample_rate = host_get_sample_rate;
  96. fHost.is_offline = host_is_offline;
  97. fHost.get_time_info = host_get_time_info;
  98. fHost.write_midi_event = host_write_midi_event;
  99. fHost.ui_parameter_changed = host_ui_parameter_changed;
  100. fHost.ui_custom_data_changed = host_ui_custom_data_changed;
  101. fHost.ui_closed = host_ui_closed;
  102. fHost.ui_open_file = host_ui_open_file;
  103. fHost.ui_save_file = host_ui_save_file;
  104. fHost.dispatcher = host_dispatcher;
  105. const LV2_Options_Option* options = nullptr;
  106. const LV2_URID_Map* uridMap = nullptr;
  107. const LV2_URID_Unmap* uridUnmap = nullptr;
  108. for (int i=0; features[i] != nullptr; ++i)
  109. {
  110. if (std::strcmp(features[i]->URI, LV2_OPTIONS__options) == 0)
  111. options = (const LV2_Options_Option*)features[i]->data;
  112. else if (std::strcmp(features[i]->URI, LV2_URID__map) == 0)
  113. uridMap = (const LV2_URID_Map*)features[i]->data;
  114. else if (std::strcmp(features[i]->URI, LV2_URID__unmap) == 0)
  115. uridUnmap = (const LV2_URID_Unmap*)features[i]->data;
  116. }
  117. if (options == nullptr || uridMap == nullptr)
  118. {
  119. carla_stderr("Host doesn't provide option or urid-map features");
  120. return;
  121. }
  122. for (int i=0; options[i].key != 0; ++i)
  123. {
  124. if (uridUnmap != nullptr)
  125. {
  126. carla_debug("Host option %i:\"%s\"", i, uridUnmap->unmap(uridUnmap->handle, options[i].key));
  127. }
  128. if (options[i].key == uridMap->map(uridMap->handle, LV2_BUF_SIZE__maxBlockLength))
  129. {
  130. if (options[i].type == uridMap->map(uridMap->handle, LV2_ATOM__Int))
  131. {
  132. const int value(*(const int*)options[i].value);
  133. CARLA_SAFE_ASSERT_CONTINUE(value > 0);
  134. fBufferSize = static_cast<uint32_t>(value);
  135. }
  136. else
  137. carla_stderr("Host provides maxBlockLength but has wrong value type");
  138. break;
  139. }
  140. }
  141. fUridMap = uridMap;
  142. if (fDescriptor->midiIns > 0)
  143. fUI.portOffset += desc->midiIns;
  144. else if (fDescriptor->hints & NATIVE_PLUGIN_USES_TIME)
  145. fUI.portOffset += 1;
  146. fUI.portOffset += desc->midiOuts;
  147. fUI.portOffset += 1; // freewheel
  148. fUI.portOffset += desc->audioIns;
  149. fUI.portOffset += desc->audioOuts;
  150. }
  151. ~NativePlugin()
  152. {
  153. CARLA_ASSERT(fHandle == nullptr);
  154. if (fHost.resourceDir != nullptr)
  155. {
  156. delete[] fHost.resourceDir;
  157. fHost.resourceDir = nullptr;
  158. }
  159. }
  160. bool init()
  161. {
  162. if (fUI.portOffset == 0)
  163. {
  164. // host is missing features
  165. return false;
  166. }
  167. if (fDescriptor->instantiate == nullptr || fDescriptor->process == nullptr)
  168. {
  169. carla_stderr("Plugin is missing something...");
  170. return false;
  171. }
  172. if (fBufferSize == 0)
  173. {
  174. carla_stderr("Host is missing bufferSize feature");
  175. //return false;
  176. // as testing, continue for now
  177. fBufferSize = 1024;
  178. }
  179. fHandle = fDescriptor->instantiate(&fHost);
  180. CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr, false);
  181. carla_zeroStructs(fMidiEvents, kMaxMidiEvents*2);
  182. carla_zeroStruct(fTimeInfo);
  183. fPorts.init(fDescriptor, fHandle);
  184. fURIs.map(fUridMap);
  185. return true;
  186. }
  187. // -------------------------------------------------------------------
  188. // LV2 functions
  189. void lv2_connect_port(const uint32_t port, void* const dataLocation)
  190. {
  191. fPorts.connectPort(fDescriptor, port, dataLocation);
  192. }
  193. void lv2_activate()
  194. {
  195. if (fDescriptor->activate != nullptr)
  196. fDescriptor->activate(fHandle);
  197. carla_zeroStruct(fTimeInfo);
  198. }
  199. void lv2_deactivate()
  200. {
  201. if (fDescriptor->deactivate != nullptr)
  202. fDescriptor->deactivate(fHandle);
  203. }
  204. void lv2_cleanup()
  205. {
  206. if (fDescriptor->cleanup != nullptr)
  207. fDescriptor->cleanup(fHandle);
  208. fHandle = nullptr;
  209. }
  210. void lv2_run(const uint32_t frames)
  211. {
  212. if (frames == 0)
  213. {
  214. updateParameterOutputs();
  215. return;
  216. }
  217. // Check for updated parameters
  218. float curValue;
  219. for (uint32_t i=0; i < fPorts.paramCount; ++i)
  220. {
  221. if (fPorts.paramsOut[i])
  222. continue;
  223. CARLA_SAFE_ASSERT_CONTINUE(fPorts.paramsPtr[i] != nullptr)
  224. curValue = *fPorts.paramsPtr[i];
  225. if (carla_isEqual(fPorts.paramsLast[i], curValue))
  226. continue;
  227. fPorts.paramsLast[i] = curValue;
  228. fDescriptor->set_parameter_value(fHandle, i, curValue);
  229. }
  230. if (fDescriptor->midiIns > 0 || fDescriptor->midiOuts > 0 || (fDescriptor->hints & NATIVE_PLUGIN_USES_TIME) != 0)
  231. {
  232. fMidiEventCount = 0;
  233. carla_zeroStructs(fMidiEvents, kMaxMidiEvents*2);
  234. if (fDescriptor->hints & NATIVE_PLUGIN_USES_TIME)
  235. {
  236. LV2_ATOM_SEQUENCE_FOREACH(fPorts.eventsIn[0], iter)
  237. {
  238. const LV2_Atom_Event* const event((const LV2_Atom_Event*)iter);
  239. if (event == nullptr)
  240. continue;
  241. if (event->body.type != fURIs.atomBlank)
  242. continue;
  243. const LV2_Atom_Object* const obj((const LV2_Atom_Object*)&event->body);
  244. if (obj->body.otype != fURIs.timePos)
  245. continue;
  246. LV2_Atom* bar = nullptr;
  247. LV2_Atom* barBeat = nullptr;
  248. LV2_Atom* beat = nullptr;
  249. LV2_Atom* beatUnit = nullptr;
  250. LV2_Atom* beatsPerBar = nullptr;
  251. LV2_Atom* beatsPerMinute = nullptr;
  252. LV2_Atom* ticksPerBeat = nullptr;
  253. LV2_Atom* frame = nullptr;
  254. LV2_Atom* speed = nullptr;
  255. lv2_atom_object_get(obj,
  256. fURIs.timeBar, &bar,
  257. fURIs.timeBarBeat, &barBeat,
  258. fURIs.timeBeat, &beat,
  259. fURIs.timeBeatUnit, &beatUnit,
  260. fURIs.timeBeatsPerBar, &beatsPerBar,
  261. fURIs.timeBeatsPerMinute, &beatsPerMinute,
  262. fURIs.timeTicksPerBeat, &ticksPerBeat,
  263. fURIs.timeFrame, &frame,
  264. fURIs.timeSpeed, &speed,
  265. nullptr);
  266. if (bar != nullptr)
  267. {
  268. /**/ if (bar->type == fURIs.atomDouble)
  269. fTimeInfo.bbt.bar = static_cast<int32_t>(((LV2_Atom_Double*)bar)->body + 1.0);
  270. else if (bar->type == fURIs.atomFloat)
  271. fTimeInfo.bbt.bar = static_cast<int32_t>(((LV2_Atom_Float*)bar)->body + 1.0f);
  272. else if (bar->type == fURIs.atomInt)
  273. fTimeInfo.bbt.bar = static_cast<int32_t>(((LV2_Atom_Int*)bar)->body + 1);
  274. else if (bar->type == fURIs.atomLong)
  275. fTimeInfo.bbt.bar = static_cast<int32_t>(((LV2_Atom_Long*)bar)->body + 1);
  276. else
  277. carla_stderr("Unknown lv2 bar value type");
  278. }
  279. if (ticksPerBeat != nullptr)
  280. {
  281. /**/ if (ticksPerBeat->type == fURIs.atomDouble)
  282. fTimeInfo.bbt.ticksPerBeat = ((LV2_Atom_Double*)ticksPerBeat)->body;
  283. else if (ticksPerBeat->type == fURIs.atomFloat)
  284. fTimeInfo.bbt.ticksPerBeat = static_cast<double>(((LV2_Atom_Float*)ticksPerBeat)->body);
  285. else if (ticksPerBeat->type == fURIs.atomInt)
  286. fTimeInfo.bbt.ticksPerBeat = static_cast<double>(((LV2_Atom_Int*)ticksPerBeat)->body);
  287. else if (ticksPerBeat->type == fURIs.atomLong)
  288. fTimeInfo.bbt.ticksPerBeat = static_cast<double>(((LV2_Atom_Long*)ticksPerBeat)->body);
  289. else
  290. carla_stderr("Unknown lv2 ticksPerBeat value type");
  291. }
  292. if (barBeat != nullptr)
  293. {
  294. double barBeatValue = 0.0;
  295. /**/ if (barBeat->type == fURIs.atomDouble)
  296. barBeatValue = ((LV2_Atom_Double*)barBeat)->body;
  297. else if (barBeat->type == fURIs.atomFloat)
  298. barBeatValue = static_cast<double>(((LV2_Atom_Float*)barBeat)->body);
  299. else if (barBeat->type == fURIs.atomInt)
  300. barBeatValue = static_cast<double>(((LV2_Atom_Int*)barBeat)->body);
  301. else if (barBeat->type == fURIs.atomLong)
  302. barBeatValue = static_cast<double>(((LV2_Atom_Long*)barBeat)->body);
  303. else
  304. carla_stderr("Unknown lv2 barBeat value type");
  305. const double rest = std::fmod(barBeatValue, 1.0);
  306. fTimeInfo.bbt.beat = static_cast<int32_t>(barBeatValue-rest+1.0);
  307. fTimeInfo.bbt.tick = static_cast<int32_t>(rest*fTimeInfo.bbt.ticksPerBeat+0.5);
  308. }
  309. // barBeat includes beat
  310. else if (beat != nullptr)
  311. {
  312. /**/ if (beat->type == fURIs.atomDouble)
  313. fTimeInfo.bbt.beat = static_cast<int32_t>(((LV2_Atom_Double*)beat)->body + 1.0);
  314. else if (beat->type == fURIs.atomFloat)
  315. fTimeInfo.bbt.beat = static_cast<int32_t>(((LV2_Atom_Float*)beat)->body + 1.0f);
  316. else if (beat->type == fURIs.atomInt)
  317. fTimeInfo.bbt.beat = static_cast<int32_t>(((LV2_Atom_Int*)beat)->body + 1);
  318. else if (beat->type == fURIs.atomLong)
  319. fTimeInfo.bbt.beat = static_cast<int32_t>(((LV2_Atom_Long*)beat)->body + 1);
  320. else
  321. carla_stderr("Unknown lv2 beat value type");
  322. }
  323. if (beatUnit != nullptr)
  324. {
  325. /**/ if (beatUnit->type == fURIs.atomDouble)
  326. fTimeInfo.bbt.beatType = static_cast<float>(((LV2_Atom_Double*)beatUnit)->body);
  327. else if (beatUnit->type == fURIs.atomFloat)
  328. fTimeInfo.bbt.beatType = ((LV2_Atom_Float*)beatUnit)->body;
  329. else if (beatUnit->type == fURIs.atomInt)
  330. fTimeInfo.bbt.beatType = static_cast<float>(((LV2_Atom_Int*)beatUnit)->body);
  331. else if (beatUnit->type == fURIs.atomLong)
  332. fTimeInfo.bbt.beatType = static_cast<float>(((LV2_Atom_Long*)beatUnit)->body);
  333. else
  334. carla_stderr("Unknown lv2 beatUnit value type");
  335. }
  336. if (beatsPerBar != nullptr)
  337. {
  338. /**/ if (beatsPerBar->type == fURIs.atomDouble)
  339. fTimeInfo.bbt.beatsPerBar = static_cast<float>(((LV2_Atom_Double*)beatsPerBar)->body);
  340. else if (beatsPerBar->type == fURIs.atomFloat)
  341. fTimeInfo.bbt.beatsPerBar = ((LV2_Atom_Float*)beatsPerBar)->body;
  342. else if (beatsPerBar->type == fURIs.atomInt)
  343. fTimeInfo.bbt.beatsPerBar = static_cast<float>(((LV2_Atom_Int*)beatsPerBar)->body);
  344. else if (beatsPerBar->type == fURIs.atomLong)
  345. fTimeInfo.bbt.beatsPerBar = static_cast<float>(((LV2_Atom_Long*)beatsPerBar)->body);
  346. else
  347. carla_stderr("Unknown lv2 beatsPerBar value type");
  348. }
  349. if (beatsPerMinute != nullptr)
  350. {
  351. /**/ if (beatsPerMinute->type == fURIs.atomDouble)
  352. fTimeInfo.bbt.beatsPerMinute = ((LV2_Atom_Double*)beatsPerMinute)->body;
  353. else if (beatsPerMinute->type == fURIs.atomFloat)
  354. fTimeInfo.bbt.beatsPerMinute = static_cast<double>(((LV2_Atom_Float*)beatsPerMinute)->body);
  355. else if (beatsPerMinute->type == fURIs.atomInt)
  356. fTimeInfo.bbt.beatsPerMinute = static_cast<double>(((LV2_Atom_Int*)beatsPerMinute)->body);
  357. else if (beatsPerMinute->type == fURIs.atomLong)
  358. fTimeInfo.bbt.beatsPerMinute = static_cast<double>(((LV2_Atom_Long*)beatsPerMinute)->body);
  359. else
  360. carla_stderr("Unknown lv2 beatsPerMinute value type");
  361. }
  362. fTimeInfo.bbt.barStartTick = fTimeInfo.bbt.ticksPerBeat*fTimeInfo.bbt.beatsPerBar*(fTimeInfo.bbt.bar-1);
  363. if (frame != nullptr && frame->type == fURIs.atomLong)
  364. fTimeInfo.frame = static_cast<uint64_t>(((LV2_Atom_Long*)frame)->body);
  365. if (speed != nullptr && speed->type == fURIs.atomFloat)
  366. {
  367. fLastTimeSpeed = ((LV2_Atom_Float*)speed)->body;
  368. fTimeInfo.playing = carla_isEqual(fLastTimeSpeed, 1.0);
  369. }
  370. fTimeInfo.bbt.valid = (beatsPerMinute != nullptr && beatsPerBar != nullptr && beatUnit != nullptr);
  371. }
  372. }
  373. for (uint32_t i=0; i < fDescriptor->midiIns; ++i)
  374. {
  375. LV2_ATOM_SEQUENCE_FOREACH(fPorts.eventsIn[i], iter)
  376. {
  377. const LV2_Atom_Event* const event((const LV2_Atom_Event*)iter);
  378. if (event == nullptr)
  379. continue;
  380. if (event->body.type != fURIs.midiEvent)
  381. continue;
  382. if (event->body.size > 4)
  383. continue;
  384. if (event->time.frames >= frames)
  385. break;
  386. if (fMidiEventCount >= kMaxMidiEvents*2)
  387. break;
  388. const uint8_t* const data((const uint8_t*)(event + 1));
  389. NativeMidiEvent& nativeEvent(fMidiEvents[fMidiEventCount++]);
  390. carla_zeroStruct(nativeEvent);
  391. nativeEvent.port = (uint8_t)i;
  392. nativeEvent.size = (uint8_t)event->body.size;
  393. nativeEvent.time = (uint32_t)event->time.frames;
  394. for (uint32_t j=0; j < event->body.size; ++j)
  395. nativeEvent.data[j] = data[j];
  396. }
  397. }
  398. }
  399. fIsProcessing = true;
  400. // FIXME
  401. fDescriptor->process(fHandle, const_cast<float**>(fPorts.audioIns), fPorts.audioOuts, frames, fMidiEvents, fMidiEventCount);
  402. fIsProcessing = false;
  403. // update timePos for next callback
  404. if (carla_isNotEqual(fLastTimeSpeed, 0.0))
  405. {
  406. const double newFrames = fLastTimeSpeed*frames;
  407. fTimeInfo.frame += static_cast<uint64_t>(newFrames);
  408. if (fTimeInfo.bbt.valid)
  409. {
  410. const double samplesPerBeat = 60.0 / fTimeInfo.bbt.beatsPerMinute * fSampleRate;
  411. const double ticksPerSample = fTimeInfo.bbt.ticksPerBeat / samplesPerBeat;
  412. double newTickPos = double(fTimeInfo.bbt.tick) + ticksPerSample*newFrames;
  413. double newBeatPos = double(fTimeInfo.bbt.beat)-1.0;
  414. double newBarPos = double(fTimeInfo.bbt.bar)-1.0;
  415. for (; newTickPos >= fTimeInfo.bbt.ticksPerBeat;)
  416. {
  417. ++newBeatPos;
  418. newTickPos -= fTimeInfo.bbt.ticksPerBeat;
  419. }
  420. for (; newBeatPos >= fTimeInfo.bbt.beatsPerBar;)
  421. {
  422. ++newBarPos;
  423. newBeatPos -= fTimeInfo.bbt.beatsPerBar;
  424. }
  425. fTimeInfo.bbt.bar = static_cast<int32_t>(newBarPos+1.0);
  426. fTimeInfo.bbt.beat = static_cast<int32_t>(newBeatPos+1.0);
  427. fTimeInfo.bbt.tick = static_cast<int32_t>(newTickPos);
  428. fTimeInfo.bbt.barStartTick = fTimeInfo.bbt.ticksPerBeat*fTimeInfo.bbt.beatsPerBar*(fTimeInfo.bbt.bar-1);
  429. }
  430. }
  431. updateParameterOutputs();
  432. if (fDescriptor->midiOuts > 0)
  433. {
  434. uint32_t capacities[fDescriptor->midiOuts];
  435. uint32_t offsets [fDescriptor->midiOuts];
  436. for (uint32_t i=0, size=fDescriptor->midiOuts; i<size; ++i)
  437. {
  438. LV2_Atom_Sequence* const seq(fPorts.midiOuts[i]);
  439. CARLA_SAFE_ASSERT_CONTINUE(seq != nullptr);
  440. capacities[i] = seq->atom.size;
  441. offsets [i] = 0;
  442. }
  443. LV2_Atom_Event* aev;
  444. uint32_t size;
  445. // reverse lookup MIDI events
  446. for (uint32_t i = (kMaxMidiEvents*2)-1; i >= fMidiEventCount; --i)
  447. {
  448. if (fMidiEvents[i].data[0] == 0)
  449. break;
  450. NativeMidiEvent& nativeEvent(fMidiEvents[i]);
  451. const uint8_t port(nativeEvent.port);
  452. CARLA_SAFE_ASSERT_CONTINUE(nativeEvent.port < fDescriptor->midiOuts);
  453. LV2_Atom_Sequence* const seq(fPorts.midiOuts[port]);
  454. CARLA_SAFE_ASSERT_CONTINUE(seq != nullptr);
  455. if (sizeof(LV2_Atom_Event) + nativeEvent.size > capacities[port] - offsets[port])
  456. continue;
  457. if (offsets[port] == 0)
  458. {
  459. seq->atom.size = 0;
  460. seq->atom.type = fURIs.atomSequence;
  461. seq->body.unit = 0;
  462. seq->body.pad = 0;
  463. }
  464. aev = (LV2_Atom_Event*)(LV2_ATOM_CONTENTS(LV2_Atom_Sequence, seq) + offsets[port]);
  465. aev->time.frames = nativeEvent.time;
  466. aev->body.size = nativeEvent.size;
  467. aev->body.type = fURIs.midiEvent;
  468. std::memcpy(LV2_ATOM_BODY(&aev->body), nativeEvent.data, nativeEvent.size);
  469. size = lv2_atom_pad_size(sizeof(LV2_Atom_Event) + nativeEvent.size);
  470. offsets[port] += size;
  471. seq->atom.size += size;
  472. }
  473. }
  474. }
  475. // -------------------------------------------------------------------
  476. uint32_t lv2_get_options(LV2_Options_Option* const /*options*/) const
  477. {
  478. // currently unused
  479. return LV2_OPTIONS_SUCCESS;
  480. }
  481. uint32_t lv2_set_options(const LV2_Options_Option* const options)
  482. {
  483. for (int i=0; options[i].key != 0; ++i)
  484. {
  485. if (options[i].key == fUridMap->map(fUridMap->handle, LV2_BUF_SIZE__maxBlockLength))
  486. {
  487. if (options[i].type == fUridMap->map(fUridMap->handle, LV2_ATOM__Int))
  488. {
  489. const int value(*(const int*)options[i].value);
  490. CARLA_SAFE_ASSERT_CONTINUE(value > 0);
  491. fBufferSize = static_cast<uint32_t>(value);
  492. if (fDescriptor->dispatcher != nullptr)
  493. fDescriptor->dispatcher(fHandle, NATIVE_PLUGIN_OPCODE_BUFFER_SIZE_CHANGED, 0, value, nullptr, 0.0f);
  494. }
  495. else
  496. carla_stderr("Host changed maxBlockLength but with wrong value type");
  497. }
  498. else if (options[i].key == fUridMap->map(fUridMap->handle, LV2_CORE__sampleRate))
  499. {
  500. if (options[i].type == fUridMap->map(fUridMap->handle, LV2_ATOM__Double))
  501. {
  502. const double value(*(const double*)options[i].value);
  503. CARLA_SAFE_ASSERT_CONTINUE(value > 0.0);
  504. fSampleRate = value;
  505. if (fDescriptor->dispatcher != nullptr)
  506. fDescriptor->dispatcher(fHandle, NATIVE_PLUGIN_OPCODE_SAMPLE_RATE_CHANGED, 0, 0, nullptr, (float)fSampleRate);
  507. }
  508. else
  509. carla_stderr("Host changed sampleRate but with wrong value type");
  510. }
  511. }
  512. return LV2_OPTIONS_SUCCESS;
  513. }
  514. const LV2_Program_Descriptor* lv2_get_program(const uint32_t index)
  515. {
  516. if (fDescriptor->category == NATIVE_PLUGIN_CATEGORY_SYNTH)
  517. return nullptr;
  518. if (fDescriptor->get_midi_program_count == nullptr)
  519. return nullptr;
  520. if (fDescriptor->get_midi_program_info == nullptr)
  521. return nullptr;
  522. if (index >= fDescriptor->get_midi_program_count(fHandle))
  523. return nullptr;
  524. const NativeMidiProgram* const midiProg(fDescriptor->get_midi_program_info(fHandle, index));
  525. if (midiProg == nullptr)
  526. return nullptr;
  527. fProgramDesc.bank = midiProg->bank;
  528. fProgramDesc.program = midiProg->program;
  529. fProgramDesc.name = midiProg->name;
  530. return &fProgramDesc;
  531. }
  532. void lv2_select_program(uint32_t bank, uint32_t program)
  533. {
  534. if (fDescriptor->category == NATIVE_PLUGIN_CATEGORY_SYNTH)
  535. return;
  536. if (fDescriptor->set_midi_program == nullptr)
  537. return;
  538. fDescriptor->set_midi_program(fHandle, 0, bank, program);
  539. for (uint32_t i=0; i < fPorts.paramCount; ++i)
  540. {
  541. fPorts.paramsLast[i] = fDescriptor->get_parameter_value(fHandle, i);
  542. if (fPorts.paramsPtr[i] != nullptr)
  543. *fPorts.paramsPtr[i] = fPorts.paramsLast[i];
  544. }
  545. }
  546. LV2_State_Status lv2_save(const LV2_State_Store_Function store, const LV2_State_Handle handle, const uint32_t /*flags*/, const LV2_Feature* const* const /*features*/) const
  547. {
  548. if ((fDescriptor->hints & NATIVE_PLUGIN_USES_STATE) == 0 || fDescriptor->get_state == nullptr)
  549. return LV2_STATE_ERR_NO_FEATURE;
  550. if (char* const state = fDescriptor->get_state(fHandle))
  551. {
  552. store(handle, fUridMap->map(fUridMap->handle, "http://kxstudio.sf.net/ns/carla/chunk"), state, std::strlen(state), fURIs.atomString, LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE);
  553. std::free(state);
  554. return LV2_STATE_SUCCESS;
  555. }
  556. return LV2_STATE_ERR_UNKNOWN;
  557. }
  558. LV2_State_Status lv2_restore(const LV2_State_Retrieve_Function retrieve, const LV2_State_Handle handle, uint32_t flags, const LV2_Feature* const* const /*features*/) const
  559. {
  560. if ((fDescriptor->hints & NATIVE_PLUGIN_USES_STATE) == 0 || fDescriptor->set_state == nullptr)
  561. return LV2_STATE_ERR_NO_FEATURE;
  562. size_t size = 0;
  563. uint32_t type = 0;
  564. const void* const data = retrieve(handle, fUridMap->map(fUridMap->handle, "http://kxstudio.sf.net/ns/carla/chunk"), &size, &type, &flags);
  565. if (size == 0)
  566. return LV2_STATE_ERR_UNKNOWN;
  567. if (type == 0)
  568. return LV2_STATE_ERR_UNKNOWN;
  569. if (data == nullptr)
  570. return LV2_STATE_ERR_UNKNOWN;
  571. if (type != fURIs.atomString)
  572. return LV2_STATE_ERR_BAD_TYPE;
  573. fDescriptor->set_state(fHandle, (const char*)data);
  574. return LV2_STATE_SUCCESS;
  575. }
  576. // -------------------------------------------------------------------
  577. void lv2ui_instantiate(LV2UI_Write_Function writeFunction, LV2UI_Controller controller,
  578. LV2UI_Widget* widget, const LV2_Feature* const* features, const bool isEmbed)
  579. {
  580. fUI.writeFunction = writeFunction;
  581. fUI.controller = controller;
  582. fUI.isEmbed = isEmbed;
  583. #ifdef CARLA_OS_LINUX
  584. // ---------------------------------------------------------------
  585. // show embed UI if needed
  586. if (isEmbed)
  587. {
  588. fUI.isVisible = true;
  589. intptr_t parentId = 0;
  590. for (int i=0; features[i] != nullptr; ++i)
  591. {
  592. if (std::strcmp(features[i]->URI, LV2_UI__parent) == 0)
  593. {
  594. parentId = (intptr_t)features[i]->data;
  595. }
  596. else if (std::strcmp(features[i]->URI, LV2_UI__resize) == 0)
  597. {
  598. const LV2UI_Resize* const uiResize((const LV2UI_Resize*)features[i]->data);
  599. uiResize->ui_resize(uiResize->handle, 740, 512);
  600. }
  601. }
  602. char strBuf[0xff+1];
  603. strBuf[0xff] = '\0';
  604. std::snprintf(strBuf, 0xff, P_INTPTR, parentId);
  605. carla_setenv("CARLA_PLUGIN_EMBED_WINID", strBuf);
  606. fDescriptor->ui_show(fHandle, true);
  607. carla_setenv("CARLA_PLUGIN_EMBED_WINID", "0");
  608. }
  609. #endif
  610. // ---------------------------------------------------------------
  611. // see if the host supports external-ui
  612. for (int i=0; features[i] != nullptr; ++i)
  613. {
  614. if (std::strcmp(features[i]->URI, LV2_EXTERNAL_UI__Host) == 0 ||
  615. std::strcmp(features[i]->URI, LV2_EXTERNAL_UI_DEPRECATED_URI) == 0)
  616. {
  617. fUI.host = (const LV2_External_UI_Host*)features[i]->data;
  618. break;
  619. }
  620. }
  621. if (fUI.host != nullptr)
  622. {
  623. fHost.uiName = carla_strdup(fUI.host->plugin_human_id);
  624. *widget = this;
  625. return;
  626. }
  627. // ---------------------------------------------------------------
  628. // no external-ui support, use showInterface
  629. for (int i=0; features[i] != nullptr; ++i)
  630. {
  631. if (std::strcmp(features[i]->URI, LV2_OPTIONS__options) == 0)
  632. {
  633. const LV2_Options_Option* const options((const LV2_Options_Option*)features[i]->data);
  634. for (int j=0; options[j].key != 0; ++j)
  635. {
  636. if (options[j].key == fUridMap->map(fUridMap->handle, LV2_UI__windowTitle))
  637. {
  638. fHost.uiName = carla_strdup((const char*)options[j].value);
  639. break;
  640. }
  641. }
  642. break;
  643. }
  644. }
  645. if (fHost.uiName == nullptr)
  646. fHost.uiName = carla_strdup(fDescriptor->name);
  647. *widget = nullptr;
  648. }
  649. void lv2ui_port_event(uint32_t portIndex, uint32_t bufferSize, uint32_t format, const void* buffer) const
  650. {
  651. if (format != 0 || bufferSize != sizeof(float) || buffer == nullptr)
  652. return;
  653. if (portIndex >= fUI.portOffset || ! fUI.isVisible)
  654. return;
  655. if (fDescriptor->ui_set_parameter_value == nullptr)
  656. return;
  657. const float value(*(const float*)buffer);
  658. fDescriptor->ui_set_parameter_value(fHandle, portIndex-fUI.portOffset, value);
  659. }
  660. void lv2ui_cleanup()
  661. {
  662. if (fUI.isVisible)
  663. handleUiHide();
  664. fUI.host = nullptr;
  665. fUI.writeFunction = nullptr;
  666. fUI.controller = nullptr;
  667. if (fHost.uiName != nullptr)
  668. {
  669. delete[] fHost.uiName;
  670. fHost.uiName = nullptr;
  671. }
  672. }
  673. // -------------------------------------------------------------------
  674. void lv2ui_select_program(uint32_t bank, uint32_t program) const
  675. {
  676. if (fDescriptor->category == NATIVE_PLUGIN_CATEGORY_SYNTH)
  677. return;
  678. if (fDescriptor->ui_set_midi_program == nullptr)
  679. return;
  680. fDescriptor->ui_set_midi_program(fHandle, 0, bank, program);
  681. }
  682. // -------------------------------------------------------------------
  683. int lv2ui_idle() const
  684. {
  685. if (! fUI.isVisible)
  686. return 1;
  687. handleUiRun();
  688. return 0;
  689. }
  690. int lv2ui_show()
  691. {
  692. handleUiShow();
  693. return 0;
  694. }
  695. int lv2ui_hide()
  696. {
  697. handleUiHide();
  698. return 0;
  699. }
  700. // -------------------------------------------------------------------
  701. protected:
  702. void handleUiRun() const
  703. {
  704. if (fDescriptor->ui_idle != nullptr)
  705. fDescriptor->ui_idle(fHandle);
  706. }
  707. void handleUiShow()
  708. {
  709. CARLA_SAFE_ASSERT_RETURN(! fUI.isEmbed,);
  710. if (fDescriptor->ui_show != nullptr)
  711. fDescriptor->ui_show(fHandle, true);
  712. fUI.isVisible = true;
  713. }
  714. void handleUiHide()
  715. {
  716. if (fDescriptor->ui_show != nullptr)
  717. fDescriptor->ui_show(fHandle, false);
  718. fUI.isVisible = false;
  719. }
  720. // -------------------------------------------------------------------
  721. uint32_t handleGetBufferSize() const
  722. {
  723. return fBufferSize;
  724. }
  725. double handleGetSampleRate() const
  726. {
  727. return fSampleRate;
  728. }
  729. bool handleIsOffline() const
  730. {
  731. CARLA_SAFE_ASSERT_RETURN(fIsProcessing, false);
  732. return (fPorts.freewheel != nullptr && *fPorts.freewheel >= 0.5f);
  733. }
  734. const NativeTimeInfo* handleGetTimeInfo() const
  735. {
  736. CARLA_SAFE_ASSERT_RETURN(fIsProcessing, nullptr);
  737. return &fTimeInfo;
  738. }
  739. bool handleWriteMidiEvent(const NativeMidiEvent* const event)
  740. {
  741. CARLA_SAFE_ASSERT_RETURN(fIsProcessing, false);
  742. CARLA_SAFE_ASSERT_RETURN(fDescriptor->midiOuts > 0, false);
  743. CARLA_SAFE_ASSERT_RETURN(event != nullptr, false);
  744. CARLA_SAFE_ASSERT_RETURN(event->data[0] != 0, false);
  745. // reverse-find first free event, and put it there
  746. for (uint32_t i=(kMaxMidiEvents*2)-1; i > fMidiEventCount; --i)
  747. {
  748. if (fMidiEvents[i].data[0] != 0)
  749. continue;
  750. std::memcpy(&fMidiEvents[i], event, sizeof(NativeMidiEvent));
  751. return true;
  752. }
  753. carla_stdout("NativePlugin::handleWriteMidiEvent(%p) - buffer full", event);
  754. return false;
  755. }
  756. void handleUiParameterChanged(const uint32_t index, const float value) const
  757. {
  758. if (fUI.writeFunction != nullptr && fUI.controller != nullptr)
  759. fUI.writeFunction(fUI.controller, index+fUI.portOffset, sizeof(float), 0, &value);
  760. }
  761. void handleUiCustomDataChanged(const char* const /*key*/, const char* const /*value*/) const
  762. {
  763. //storeCustomData(key, value);
  764. }
  765. void handleUiClosed()
  766. {
  767. if (fUI.host != nullptr && fUI.host->ui_closed != nullptr && fUI.controller != nullptr)
  768. fUI.host->ui_closed(fUI.controller);
  769. fUI.host = nullptr;
  770. fUI.writeFunction = nullptr;
  771. fUI.controller = nullptr;
  772. fUI.isVisible = false;
  773. }
  774. const char* handleUiOpenFile(const bool /*isDir*/, const char* const /*title*/, const char* const /*filter*/) const
  775. {
  776. // TODO
  777. return nullptr;
  778. }
  779. const char* handleUiSaveFile(const bool /*isDir*/, const char* const /*title*/, const char* const /*filter*/) const
  780. {
  781. // TODO
  782. return nullptr;
  783. }
  784. intptr_t handleDispatcher(const NativeHostDispatcherOpcode opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt)
  785. {
  786. carla_debug("NativePlugin::handleDispatcher(%i, %i, " P_INTPTR ", %p, %f)", opcode, index, value, ptr, opt);
  787. intptr_t ret = 0;
  788. switch (opcode)
  789. {
  790. case NATIVE_HOST_OPCODE_NULL:
  791. case NATIVE_HOST_OPCODE_UPDATE_PARAMETER:
  792. case NATIVE_HOST_OPCODE_UPDATE_MIDI_PROGRAM:
  793. case NATIVE_HOST_OPCODE_RELOAD_PARAMETERS:
  794. case NATIVE_HOST_OPCODE_RELOAD_MIDI_PROGRAMS:
  795. case NATIVE_HOST_OPCODE_RELOAD_ALL:
  796. case NATIVE_HOST_OPCODE_HOST_IDLE:
  797. // nothing
  798. break;
  799. case NATIVE_HOST_OPCODE_UI_UNAVAILABLE:
  800. handleUiClosed();
  801. break;
  802. }
  803. return ret;
  804. // unused for now
  805. (void)index;
  806. (void)value;
  807. (void)ptr;
  808. (void)opt;
  809. }
  810. void updateParameterOutputs()
  811. {
  812. for (uint32_t i=0; i < fPorts.paramCount; ++i)
  813. {
  814. if (! fPorts.paramsOut[i])
  815. continue;
  816. fPorts.paramsLast[i] = fDescriptor->get_parameter_value(fHandle, i);
  817. if (fPorts.paramsPtr[i] != nullptr)
  818. *fPorts.paramsPtr[i] = fPorts.paramsLast[i];
  819. }
  820. }
  821. // -------------------------------------------------------------------
  822. private:
  823. // Native data
  824. NativePluginHandle fHandle;
  825. NativeHostDescriptor fHost;
  826. const NativePluginDescriptor* const fDescriptor;
  827. LV2_Program_Descriptor fProgramDesc;
  828. uint32_t fMidiEventCount;
  829. NativeMidiEvent fMidiEvents[kMaxMidiEvents*2];
  830. NativeTimeInfo fTimeInfo;
  831. double fLastTimeSpeed;
  832. bool fIsProcessing;
  833. // Lv2 host data
  834. uint32_t fBufferSize;
  835. double fSampleRate;
  836. const LV2_URID_Map* fUridMap;
  837. struct URIDs {
  838. LV2_URID atomBlank;
  839. LV2_URID atomDouble;
  840. LV2_URID atomFloat;
  841. LV2_URID atomInt;
  842. LV2_URID atomLong;
  843. LV2_URID atomSequence;
  844. LV2_URID atomString;
  845. LV2_URID midiEvent;
  846. LV2_URID timePos;
  847. LV2_URID timeBar;
  848. LV2_URID timeBeat;
  849. LV2_URID timeBarBeat;
  850. LV2_URID timeBeatsPerBar;
  851. LV2_URID timeBeatsPerMinute;
  852. LV2_URID timeBeatUnit;
  853. LV2_URID timeFrame;
  854. LV2_URID timeSpeed;
  855. LV2_URID timeTicksPerBeat;
  856. URIDs()
  857. : atomBlank(0),
  858. atomDouble(0),
  859. atomFloat(0),
  860. atomInt(0),
  861. atomLong(0),
  862. atomSequence(0),
  863. atomString(0),
  864. midiEvent(0),
  865. timePos(0),
  866. timeBar(0),
  867. timeBeat(0),
  868. timeBarBeat(0),
  869. timeBeatsPerBar(0),
  870. timeBeatsPerMinute(0),
  871. timeBeatUnit(0),
  872. timeFrame(0),
  873. timeSpeed(0),
  874. timeTicksPerBeat(0) {}
  875. void map(const LV2_URID_Map* const uridMap)
  876. {
  877. atomBlank = uridMap->map(uridMap->handle, LV2_ATOM__Blank);
  878. atomDouble = uridMap->map(uridMap->handle, LV2_ATOM__Double);
  879. atomFloat = uridMap->map(uridMap->handle, LV2_ATOM__Float);
  880. atomInt = uridMap->map(uridMap->handle, LV2_ATOM__Int);
  881. atomLong = uridMap->map(uridMap->handle, LV2_ATOM__Long);
  882. atomSequence = uridMap->map(uridMap->handle, LV2_ATOM__Sequence);
  883. atomString = uridMap->map(uridMap->handle, LV2_ATOM__String);
  884. midiEvent = uridMap->map(uridMap->handle, LV2_MIDI__MidiEvent);
  885. timePos = uridMap->map(uridMap->handle, LV2_TIME__Position);
  886. timeBar = uridMap->map(uridMap->handle, LV2_TIME__bar);
  887. timeBeat = uridMap->map(uridMap->handle, LV2_TIME__beat);
  888. timeBarBeat = uridMap->map(uridMap->handle, LV2_TIME__barBeat);
  889. timeBeatUnit = uridMap->map(uridMap->handle, LV2_TIME__beatUnit);
  890. timeFrame = uridMap->map(uridMap->handle, LV2_TIME__frame);
  891. timeSpeed = uridMap->map(uridMap->handle, LV2_TIME__speed);
  892. timeBeatsPerBar = uridMap->map(uridMap->handle, LV2_TIME__beatsPerBar);
  893. timeBeatsPerMinute = uridMap->map(uridMap->handle, LV2_TIME__beatsPerMinute);
  894. timeTicksPerBeat = uridMap->map(uridMap->handle, LV2_KXSTUDIO_PROPERTIES__TimePositionTicksPerBeat);
  895. }
  896. } fURIs;
  897. struct UI {
  898. const LV2_External_UI_Host* host;
  899. LV2UI_Write_Function writeFunction;
  900. LV2UI_Controller controller;
  901. uint32_t portOffset;
  902. bool isEmbed;
  903. bool isVisible;
  904. UI()
  905. : host(nullptr),
  906. writeFunction(nullptr),
  907. controller(nullptr),
  908. portOffset(0),
  909. isEmbed(false),
  910. isVisible(false) {}
  911. } fUI;
  912. struct Ports {
  913. const LV2_Atom_Sequence** eventsIn;
  914. /* */ LV2_Atom_Sequence** midiOuts;
  915. const float** audioIns;
  916. /* */ float** audioOuts;
  917. float* freewheel;
  918. uint32_t paramCount;
  919. float* paramsLast;
  920. float** paramsPtr;
  921. bool* paramsOut;
  922. Ports()
  923. : eventsIn(nullptr),
  924. midiOuts(nullptr),
  925. audioIns(nullptr),
  926. audioOuts(nullptr),
  927. freewheel(nullptr),
  928. paramCount(0),
  929. paramsLast(nullptr),
  930. paramsPtr(nullptr),
  931. paramsOut(nullptr) {}
  932. ~Ports()
  933. {
  934. if (eventsIn != nullptr)
  935. {
  936. delete[] eventsIn;
  937. eventsIn = nullptr;
  938. }
  939. if (midiOuts != nullptr)
  940. {
  941. delete[] midiOuts;
  942. midiOuts = nullptr;
  943. }
  944. if (audioIns != nullptr)
  945. {
  946. delete[] audioIns;
  947. audioIns = nullptr;
  948. }
  949. if (audioOuts != nullptr)
  950. {
  951. delete[] audioOuts;
  952. audioOuts = nullptr;
  953. }
  954. if (paramsLast != nullptr)
  955. {
  956. delete[] paramsLast;
  957. paramsLast = nullptr;
  958. }
  959. if (paramsPtr != nullptr)
  960. {
  961. delete[] paramsPtr;
  962. paramsPtr = nullptr;
  963. }
  964. if (paramsOut != nullptr)
  965. {
  966. delete[] paramsOut;
  967. paramsOut = nullptr;
  968. }
  969. }
  970. void init(const NativePluginDescriptor* const desc, NativePluginHandle handle)
  971. {
  972. CARLA_SAFE_ASSERT_RETURN(desc != nullptr && handle != nullptr,)
  973. if (desc->midiIns > 0)
  974. {
  975. eventsIn = new const LV2_Atom_Sequence*[desc->midiIns];
  976. for (uint32_t i=0; i < desc->midiIns; ++i)
  977. eventsIn[i] = nullptr;
  978. }
  979. else if (desc->hints & NATIVE_PLUGIN_USES_TIME)
  980. {
  981. eventsIn = new const LV2_Atom_Sequence*[1];
  982. eventsIn[0] = nullptr;
  983. }
  984. if (desc->midiOuts > 0)
  985. {
  986. midiOuts = new LV2_Atom_Sequence*[desc->midiOuts];
  987. for (uint32_t i=0; i < desc->midiOuts; ++i)
  988. midiOuts[i] = nullptr;
  989. }
  990. if (desc->audioIns > 0)
  991. {
  992. audioIns = new const float*[desc->audioIns];
  993. for (uint32_t i=0; i < desc->audioIns; ++i)
  994. audioIns[i] = nullptr;
  995. }
  996. if (desc->audioOuts > 0)
  997. {
  998. audioOuts = new float*[desc->audioOuts];
  999. for (uint32_t i=0; i < desc->audioOuts; ++i)
  1000. audioOuts[i] = nullptr;
  1001. }
  1002. if (desc->get_parameter_count != nullptr && desc->get_parameter_info != nullptr && desc->get_parameter_value != nullptr && desc->set_parameter_value != nullptr)
  1003. {
  1004. paramCount = desc->get_parameter_count(handle);
  1005. if (paramCount > 0)
  1006. {
  1007. paramsLast = new float[paramCount];
  1008. paramsPtr = new float*[paramCount];
  1009. paramsOut = new bool[paramCount];
  1010. for (uint32_t i=0; i < paramCount; ++i)
  1011. {
  1012. paramsLast[i] = desc->get_parameter_value(handle, i);
  1013. paramsPtr [i] = nullptr;
  1014. paramsOut [i] = (desc->get_parameter_info(handle, i)->hints & NATIVE_PARAMETER_IS_OUTPUT);
  1015. }
  1016. }
  1017. }
  1018. }
  1019. void connectPort(const NativePluginDescriptor* const desc, const uint32_t port, void* const dataLocation)
  1020. {
  1021. uint32_t index = 0;
  1022. if (desc->midiIns > 0 || (desc->hints & NATIVE_PLUGIN_USES_TIME) != 0)
  1023. {
  1024. if (port == index++)
  1025. {
  1026. eventsIn[0] = (LV2_Atom_Sequence*)dataLocation;
  1027. return;
  1028. }
  1029. }
  1030. for (uint32_t i=1; i < desc->midiIns; ++i)
  1031. {
  1032. if (port == index++)
  1033. {
  1034. eventsIn[i] = (LV2_Atom_Sequence*)dataLocation;
  1035. return;
  1036. }
  1037. }
  1038. for (uint32_t i=0; i < desc->midiOuts; ++i)
  1039. {
  1040. if (port == index++)
  1041. {
  1042. midiOuts[i] = (LV2_Atom_Sequence*)dataLocation;
  1043. return;
  1044. }
  1045. }
  1046. if (port == index++)
  1047. {
  1048. freewheel = (float*)dataLocation;
  1049. return;
  1050. }
  1051. for (uint32_t i=0; i < desc->audioIns; ++i)
  1052. {
  1053. if (port == index++)
  1054. {
  1055. audioIns[i] = (float*)dataLocation;
  1056. return;
  1057. }
  1058. }
  1059. for (uint32_t i=0; i < desc->audioOuts; ++i)
  1060. {
  1061. if (port == index++)
  1062. {
  1063. audioOuts[i] = (float*)dataLocation;
  1064. return;
  1065. }
  1066. }
  1067. for (uint32_t i=0; i < paramCount; ++i)
  1068. {
  1069. if (port == index++)
  1070. {
  1071. paramsPtr[i] = (float*)dataLocation;
  1072. return;
  1073. }
  1074. }
  1075. }
  1076. CARLA_DECLARE_NON_COPY_STRUCT(Ports);
  1077. } fPorts;
  1078. SharedResourcePointer<ScopedJuceInitialiser_GUI> sJuceInitialiser;
  1079. // -------------------------------------------------------------------
  1080. #define handlePtr ((NativePlugin*)self)
  1081. static void extui_run(LV2_External_UI_Widget_Compat* self)
  1082. {
  1083. handlePtr->handleUiRun();
  1084. }
  1085. static void extui_show(LV2_External_UI_Widget_Compat* self)
  1086. {
  1087. handlePtr->handleUiShow();
  1088. }
  1089. static void extui_hide(LV2_External_UI_Widget_Compat* self)
  1090. {
  1091. handlePtr->handleUiHide();
  1092. }
  1093. #undef handlePtr
  1094. // -------------------------------------------------------------------
  1095. #define handlePtr ((NativePlugin*)handle)
  1096. static uint32_t host_get_buffer_size(NativeHostHandle handle)
  1097. {
  1098. return handlePtr->handleGetBufferSize();
  1099. }
  1100. static double host_get_sample_rate(NativeHostHandle handle)
  1101. {
  1102. return handlePtr->handleGetSampleRate();
  1103. }
  1104. static bool host_is_offline(NativeHostHandle handle)
  1105. {
  1106. return handlePtr->handleIsOffline();
  1107. }
  1108. static const NativeTimeInfo* host_get_time_info(NativeHostHandle handle)
  1109. {
  1110. return handlePtr->handleGetTimeInfo();
  1111. }
  1112. static bool host_write_midi_event(NativeHostHandle handle, const NativeMidiEvent* event)
  1113. {
  1114. return handlePtr->handleWriteMidiEvent(event);
  1115. }
  1116. static void host_ui_parameter_changed(NativeHostHandle handle, uint32_t index, float value)
  1117. {
  1118. handlePtr->handleUiParameterChanged(index, value);
  1119. }
  1120. static void host_ui_custom_data_changed(NativeHostHandle handle, const char* key, const char* value)
  1121. {
  1122. handlePtr->handleUiCustomDataChanged(key, value);
  1123. }
  1124. static void host_ui_closed(NativeHostHandle handle)
  1125. {
  1126. handlePtr->handleUiClosed();
  1127. }
  1128. static const char* host_ui_open_file(NativeHostHandle handle, bool isDir, const char* title, const char* filter)
  1129. {
  1130. return handlePtr->handleUiOpenFile(isDir, title, filter);
  1131. }
  1132. static const char* host_ui_save_file(NativeHostHandle handle, bool isDir, const char* title, const char* filter)
  1133. {
  1134. return handlePtr->handleUiSaveFile(isDir, title, filter);
  1135. }
  1136. static intptr_t host_dispatcher(NativeHostHandle handle, NativeHostDispatcherOpcode opcode, int32_t index, intptr_t value, void* ptr, float opt)
  1137. {
  1138. return handlePtr->handleDispatcher(opcode, index, value, ptr, opt);
  1139. }
  1140. #undef handlePtr
  1141. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NativePlugin)
  1142. };
  1143. // -----------------------------------------------------------------------
  1144. // LV2 plugin descriptor functions
  1145. static LV2_Handle lv2_instantiate(const LV2_Descriptor* lv2Descriptor, double sampleRate, const char* bundlePath, const LV2_Feature* const* features)
  1146. {
  1147. carla_debug("lv2_instantiate(%p, %g, %s, %p)", lv2Descriptor, sampleRate, bundlePath, features);
  1148. const NativePluginDescriptor* pluginDesc = nullptr;
  1149. const char* pluginLabel = nullptr;
  1150. if (std::strncmp(lv2Descriptor->URI, "http://kxstudio.sf.net/carla/plugins/", 37) == 0)
  1151. pluginLabel = lv2Descriptor->URI+37;
  1152. if (pluginLabel == nullptr)
  1153. {
  1154. carla_stderr("Failed to find carla native plugin with URI \"%s\"", lv2Descriptor->URI);
  1155. return nullptr;
  1156. }
  1157. carla_debug("lv2_instantiate() - looking up label \"%s\"", pluginLabel);
  1158. PluginListManager& plm(PluginListManager::getInstance());
  1159. for (LinkedList<const NativePluginDescriptor*>::Itenerator it = plm.descs.begin2(); it.valid(); it.next())
  1160. {
  1161. const NativePluginDescriptor* const& tmpDesc(it.getValue());
  1162. if (std::strcmp(tmpDesc->label, pluginLabel) == 0)
  1163. {
  1164. pluginDesc = tmpDesc;
  1165. break;
  1166. }
  1167. }
  1168. if (pluginDesc == nullptr)
  1169. {
  1170. carla_stderr("Failed to find carla native plugin with label \"%s\"", pluginLabel);
  1171. return nullptr;
  1172. }
  1173. NativePlugin* const plugin(new NativePlugin(pluginDesc, sampleRate, bundlePath, features));
  1174. if (! plugin->init())
  1175. {
  1176. carla_stderr("Failed to init plugin");
  1177. delete plugin;
  1178. return nullptr;
  1179. }
  1180. return (LV2_Handle)plugin;
  1181. }
  1182. #define instancePtr ((NativePlugin*)instance)
  1183. static void lv2_connect_port(LV2_Handle instance, uint32_t port, void* dataLocation)
  1184. {
  1185. instancePtr->lv2_connect_port(port, dataLocation);
  1186. }
  1187. static void lv2_activate(LV2_Handle instance)
  1188. {
  1189. carla_debug("lv2_activate(%p)", instance);
  1190. instancePtr->lv2_activate();
  1191. }
  1192. static void lv2_run(LV2_Handle instance, uint32_t sampleCount)
  1193. {
  1194. instancePtr->lv2_run(sampleCount);
  1195. }
  1196. static void lv2_deactivate(LV2_Handle instance)
  1197. {
  1198. carla_debug("lv2_deactivate(%p)", instance);
  1199. instancePtr->lv2_deactivate();
  1200. }
  1201. static void lv2_cleanup(LV2_Handle instance)
  1202. {
  1203. carla_debug("lv2_cleanup(%p)", instance);
  1204. instancePtr->lv2_cleanup();
  1205. delete instancePtr;
  1206. }
  1207. static uint32_t lv2_get_options(LV2_Handle instance, LV2_Options_Option* options)
  1208. {
  1209. carla_debug("lv2_get_options(%p, %p)", instance, options);
  1210. return instancePtr->lv2_get_options(options);
  1211. }
  1212. static uint32_t lv2_set_options(LV2_Handle instance, const LV2_Options_Option* options)
  1213. {
  1214. carla_debug("lv2_set_options(%p, %p)", instance, options);
  1215. return instancePtr->lv2_set_options(options);
  1216. }
  1217. static const LV2_Program_Descriptor* lv2_get_program(LV2_Handle instance, uint32_t index)
  1218. {
  1219. carla_debug("lv2_get_program(%p, %i)", instance, index);
  1220. return instancePtr->lv2_get_program(index);
  1221. }
  1222. static void lv2_select_program(LV2_Handle instance, uint32_t bank, uint32_t program)
  1223. {
  1224. carla_debug("lv2_select_program(%p, %i, %i)", instance, bank, program);
  1225. return instancePtr->lv2_select_program(bank, program);
  1226. }
  1227. static LV2_State_Status lv2_save(LV2_Handle instance, LV2_State_Store_Function store, LV2_State_Handle handle, uint32_t flags, const LV2_Feature* const* features)
  1228. {
  1229. carla_debug("lv2_save(%p, %p, %p, %i, %p)", instance, store, handle, flags, features);
  1230. return instancePtr->lv2_save(store, handle, flags, features);
  1231. }
  1232. static LV2_State_Status lv2_restore(LV2_Handle instance, LV2_State_Retrieve_Function retrieve, LV2_State_Handle handle, uint32_t flags, const LV2_Feature* const* features)
  1233. {
  1234. carla_debug("lv2_restore(%p, %p, %p, %i, %p)", instance, retrieve, handle, flags, features);
  1235. return instancePtr->lv2_restore(retrieve, handle, flags, features);
  1236. }
  1237. static const void* lv2_extension_data(const char* uri)
  1238. {
  1239. carla_debug("lv2_extension_data(\"%s\")", uri);
  1240. static const LV2_Options_Interface options = { lv2_get_options, lv2_set_options };
  1241. static const LV2_Programs_Interface programs = { lv2_get_program, lv2_select_program };
  1242. static const LV2_State_Interface state = { lv2_save, lv2_restore };
  1243. if (std::strcmp(uri, LV2_OPTIONS__interface) == 0)
  1244. return &options;
  1245. if (std::strcmp(uri, LV2_PROGRAMS__Interface) == 0)
  1246. return &programs;
  1247. if (std::strcmp(uri, LV2_STATE__interface) == 0)
  1248. return &state;
  1249. return nullptr;
  1250. }
  1251. #undef instancePtr
  1252. // -----------------------------------------------------------------------
  1253. // LV2 UI descriptor functions
  1254. static LV2UI_Handle lv2ui_instantiate(LV2UI_Write_Function writeFunction, LV2UI_Controller controller,
  1255. LV2UI_Widget* widget, const LV2_Feature* const* features, const bool isEmbed)
  1256. {
  1257. carla_debug("lv2ui_instantiate(..., %p, %p, %p)", writeFunction, controller, widget, features);
  1258. #ifndef CARLA_OS_LINUX
  1259. CARLA_SAFE_ASSERT_RETURN(! isEmbed, nullptr);
  1260. #endif
  1261. NativePlugin* plugin = nullptr;
  1262. for (int i=0; features[i] != nullptr; ++i)
  1263. {
  1264. if (std::strcmp(features[i]->URI, LV2_INSTANCE_ACCESS_URI) == 0)
  1265. {
  1266. plugin = (NativePlugin*)features[i]->data;
  1267. break;
  1268. }
  1269. }
  1270. if (plugin == nullptr)
  1271. {
  1272. carla_stderr("Host doesn't support instance-access, cannot show UI");
  1273. return nullptr;
  1274. }
  1275. plugin->lv2ui_instantiate(writeFunction, controller, widget, features, isEmbed);
  1276. return (LV2UI_Handle)plugin;
  1277. }
  1278. #ifdef CARLA_OS_LINUX
  1279. static LV2UI_Handle lv2ui_instantiate_embed(const LV2UI_Descriptor*, const char*, const char*,
  1280. LV2UI_Write_Function writeFunction, LV2UI_Controller controller,
  1281. LV2UI_Widget* widget, const LV2_Feature* const* features)
  1282. {
  1283. return lv2ui_instantiate(writeFunction, controller, widget, features, true);
  1284. }
  1285. #endif
  1286. static LV2UI_Handle lv2ui_instantiate_external(const LV2UI_Descriptor*, const char*, const char*,
  1287. LV2UI_Write_Function writeFunction, LV2UI_Controller controller,
  1288. LV2UI_Widget* widget, const LV2_Feature* const* features)
  1289. {
  1290. return lv2ui_instantiate(writeFunction, controller, widget, features, false);
  1291. }
  1292. #define uiPtr ((NativePlugin*)ui)
  1293. static void lv2ui_port_event(LV2UI_Handle ui, uint32_t portIndex, uint32_t bufferSize, uint32_t format, const void* buffer)
  1294. {
  1295. carla_debug("lv2ui_port_event(%p, %i, %i, %i, %p)", ui, portIndex, bufferSize, format, buffer);
  1296. uiPtr->lv2ui_port_event(portIndex, bufferSize, format, buffer);
  1297. }
  1298. static void lv2ui_cleanup(LV2UI_Handle ui)
  1299. {
  1300. carla_debug("lv2ui_cleanup(%p)", ui);
  1301. uiPtr->lv2ui_cleanup();
  1302. }
  1303. static void lv2ui_select_program(LV2UI_Handle ui, uint32_t bank, uint32_t program)
  1304. {
  1305. carla_debug("lv2ui_select_program(%p, %i, %i)", ui, bank, program);
  1306. uiPtr->lv2ui_select_program(bank, program);
  1307. }
  1308. static int lv2ui_idle(LV2UI_Handle ui)
  1309. {
  1310. return uiPtr->lv2ui_idle();
  1311. }
  1312. static int lv2ui_show(LV2UI_Handle ui)
  1313. {
  1314. carla_debug("lv2ui_show(%p)", ui);
  1315. return uiPtr->lv2ui_show();
  1316. }
  1317. static int lv2ui_hide(LV2UI_Handle ui)
  1318. {
  1319. carla_debug("lv2ui_hide(%p)", ui);
  1320. return uiPtr->lv2ui_hide();
  1321. }
  1322. static const void* lv2ui_extension_data(const char* uri)
  1323. {
  1324. carla_stdout("lv2ui_extension_data(\"%s\")", uri);
  1325. static const LV2UI_Idle_Interface uiidle = { lv2ui_idle };
  1326. static const LV2UI_Show_Interface uishow = { lv2ui_show, lv2ui_hide };
  1327. static const LV2_Programs_UI_Interface uiprograms = { lv2ui_select_program };
  1328. if (std::strcmp(uri, LV2_UI__idleInterface) == 0)
  1329. return &uiidle;
  1330. if (std::strcmp(uri, LV2_UI__showInterface) == 0)
  1331. return &uishow;
  1332. if (std::strcmp(uri, LV2_PROGRAMS__UIInterface) == 0)
  1333. return &uiprograms;
  1334. return nullptr;
  1335. }
  1336. #undef uiPtr
  1337. // -----------------------------------------------------------------------
  1338. // Startup code
  1339. CARLA_EXPORT
  1340. const LV2_Descriptor* lv2_descriptor(uint32_t index)
  1341. {
  1342. carla_debug("lv2_descriptor(%i)", index);
  1343. PluginListManager& plm(PluginListManager::getInstance());
  1344. if (index >= plm.descs.count())
  1345. {
  1346. carla_debug("lv2_descriptor(%i) - out of bounds", index);
  1347. return nullptr;
  1348. }
  1349. if (index < plm.lv2Descs.count())
  1350. {
  1351. carla_debug("lv2_descriptor(%i) - found previously allocated", index);
  1352. return plm.lv2Descs.getAt(index, nullptr);
  1353. }
  1354. const NativePluginDescriptor* const pluginDesc(plm.descs.getAt(index, nullptr));
  1355. CARLA_SAFE_ASSERT_RETURN(pluginDesc != nullptr, nullptr);
  1356. CarlaString tmpURI;
  1357. tmpURI = "http://kxstudio.sf.net/carla/plugins/";
  1358. tmpURI += pluginDesc->label;
  1359. carla_debug("lv2_descriptor(%i) - not found, allocating new with uri \"%s\"", index, (const char*)tmpURI);
  1360. const LV2_Descriptor lv2DescTmp = {
  1361. /* URI */ carla_strdup(tmpURI),
  1362. /* instantiate */ lv2_instantiate,
  1363. /* connect_port */ lv2_connect_port,
  1364. /* activate */ lv2_activate,
  1365. /* run */ lv2_run,
  1366. /* deactivate */ lv2_deactivate,
  1367. /* cleanup */ lv2_cleanup,
  1368. /* extension_data */ lv2_extension_data
  1369. };
  1370. LV2_Descriptor* const lv2Desc(new LV2_Descriptor);
  1371. std::memcpy(lv2Desc, &lv2DescTmp, sizeof(LV2_Descriptor));
  1372. plm.lv2Descs.append(lv2Desc);
  1373. return lv2Desc;
  1374. }
  1375. CARLA_EXPORT
  1376. const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index)
  1377. {
  1378. carla_debug("lv2ui_descriptor(%i)", index);
  1379. #ifdef CARLA_OS_LINUX
  1380. static const LV2UI_Descriptor lv2UiEmbedDesc = {
  1381. /* URI */ "http://kxstudio.sf.net/carla/ui-embed",
  1382. /* instantiate */ lv2ui_instantiate_embed,
  1383. /* cleanup */ lv2ui_cleanup,
  1384. /* port_event */ lv2ui_port_event,
  1385. /* extension_data */ lv2ui_extension_data
  1386. };
  1387. if (index == 0)
  1388. return &lv2UiEmbedDesc;
  1389. else
  1390. --index;
  1391. #endif
  1392. static const LV2UI_Descriptor lv2UiExtDesc = {
  1393. /* URI */ "http://kxstudio.sf.net/carla/ui-ext",
  1394. /* instantiate */ lv2ui_instantiate_external,
  1395. /* cleanup */ lv2ui_cleanup,
  1396. /* port_event */ lv2ui_port_event,
  1397. /* extension_data */ lv2ui_extension_data
  1398. };
  1399. return (index == 0) ? &lv2UiExtDesc : nullptr;
  1400. }
  1401. // -----------------------------------------------------------------------