diff --git a/examples/amp_plugin.nim b/examples/amp_plugin.nim index 38f8cab..858f0ba 100644 --- a/examples/amp_plugin.nim +++ b/examples/amp_plugin.nim @@ -60,7 +60,7 @@ proc connectPort(instance: Lv2Handle; port: cuint; proc activate(instance: Lv2Handle) {.cdecl.} = let plug = cast[ptr AmpPlugin](instance) - plug.log.note("nymph amp plugin activated.") + plug.log.note("nymph amp LV2 plugin activated.") proc run(instance: Lv2Handle; nSamples: cuint) {.cdecl.} = @@ -71,12 +71,12 @@ proc run(instance: Lv2Handle; nSamples: cuint) {.cdecl.} = proc deactivate(instance: Lv2Handle) {.cdecl.} = let plug = cast[ptr AmpPlugin](instance) - plug.log.note("nymph amp plugin deactivated.") + plug.log.note("nymph amp LV2 plugin deactivated.") -proc cleanup(instance: Lv2Handle) {.cdecl.} = +proc cleanupInstance(instance: Lv2Handle) {.cdecl.} = let plug = cast[ptr AmpPlugin](instance) - plug.log.note("De-allocating nymph amp plugin instance.") + plug.log.note("nymph amp LV2 plugin instance will be de-allocated.") freeShared(cast[ptr AmpPlugin](instance)) @@ -85,26 +85,44 @@ proc extensionData(uri: cstring): pointer {.cdecl.} = proc NimMain() {.cdecl, importc.} +proc NimDestroyGlobals() {.cdecl, importc.} -let descriptor = Lv2Descriptor( +let pluginDescriptor = Lv2Descriptor( uri: cstring(PluginUri), instantiate: instantiate, connectPort: connectPort, activate: activate, run: run, deactivate: deactivate, - cleanup: cleanup, + cleanup: cleanupInstance, extensionData: extensionData, ) -proc lv2Descriptor(index: cuint): ptr Lv2Descriptor {. - cdecl, exportc, dynlib, extern: "lv2_descriptor".} = - echo fmt"nymph am plugin descriptor #{index} requested" +proc cleanupLib(handle: Lv2LibHandle) {.cdecl.} = + echo "Cleaning up nymph amp library globals." + NimDestroyGlobals() + +proc getPlugin(handle: Lv2Libhandle, index: cuint): ptr Lv2Descriptor {.cdecl.} = if index == 0: - NimMain() - return addr(descriptor) + echo &"Providing nymph amp LV2 plugin descriptor #{index} to host." + return addr(pluginDescriptor) return nil + + +let libDescriptor = Lv2LibDescriptor( + handle: cast[Lv2LibHandle](nil), + size: sizeof(Lv2LibDescriptor).cuint, + cleanup: cleanupLib, + getPlugin: getPlugin, +) + + +proc lv2LibDescriptor(bundlePath: cstring, features: ptr UncheckedArray[ptr Lv2Feature]): ptr Lv2LibDescriptor {. + cdecl, dynlib, exportc: "lv2_lib_descriptor".} = + NimMain() + echo "Providing nymph amp LV2 library descriptor to host." + return addr(libDescriptor) diff --git a/nymph.nimble b/nymph.nimble index 1e05282..85a7e05 100644 --- a/nymph.nimble +++ b/nymph.nimble @@ -11,7 +11,7 @@ srcDir = "src" # Dependencies -requires "nim >= 2.0" +requires "nim >= 2.2.2" # Custom tasks @@ -89,7 +89,7 @@ task lv2lint, "Run lv2lint check on given example plugin": let ex = getExample("lv2lint") if fileExists(ex.dll): - exec(&"lv2lint -s NimMain -s NimDestroyGlobals -I \"{ex.bundle}\" \"{ex.uri}\"") + exec(&"lv2lint -s NimMain -s NimDestroyGlobals -s lv2_lib_descriptor -I \"{ex.bundle}\" \"{ex.uri}\"") else: echo &"Example '{ex.name}' shared library not found. Use task 'build_ex' to build it." diff --git a/src/nymph/core.nim b/src/nymph/core.nim index 6c137b2..d74c1e7 100644 --- a/src/nymph/core.nim +++ b/src/nymph/core.nim @@ -95,27 +95,29 @@ const type Lv2Handle* = distinct pointer -type Lv2Feature* = object - uri*: cstring - data*: pointer + Lv2LibHandle* = distinct pointer -type Lv2Descriptor* = object - uri*: cstring + Lv2Feature* = object + uri*: cstring + data*: pointer - instantiate*: proc(descriptor: ptr Lv2Descriptor, sampleRate: cdouble, bundlePath: cstring, - features: ptr UncheckedArray[ptr Lv2Feature]): Lv2Handle {.cdecl.} + Lv2Descriptor* = object + uri*: cstring + instantiate*: proc(descriptor: ptr Lv2Descriptor, sampleRate: cdouble, bundlePath: cstring, + features: ptr UncheckedArray[ptr Lv2Feature]): Lv2Handle {.cdecl.} + connectPort*: proc(instance: Lv2Handle, port: cuint, dataLocation: pointer) {.cdecl.} + activate*: proc(instance: Lv2Handle) {.cdecl.} + run*: proc(instance: Lv2Handle, sampleCount: cuint) {.cdecl.} + deactivate*: proc(instance: Lv2Handle) {.cdecl.} + cleanup*: proc(instance: Lv2Handle) {.cdecl.} + extensionData*: proc(uri: cstring): pointer {.cdecl.} - connectPort*: proc(instance: Lv2Handle, port: cuint, dataLocation: pointer) {.cdecl.} + Lv2LibDescriptor* = object + handle*: Lv2LibHandle + size*: cuint + cleanup*: proc(handle: Lv2LibHandle) {.cdecl.} + getPlugin*: proc(handle: Lv2LibHandle, index: cuint): ptr Lv2Descriptor {.cdecl.} - activate*: proc(instance: Lv2Handle) {.cdecl.} - - run*: proc(instance: Lv2Handle, sampleCount: cuint) {.cdecl.} - - deactivate*: proc(instance: Lv2Handle) {.cdecl.} - - cleanup*: proc(instance: Lv2Handle) {.cdecl.} - - extensionData*: proc(uri: cstring): pointer {.cdecl.} - -type lv2Descriptor* = proc(index: cuint): ptr Lv2Descriptor {.cdecl.} + lv2Descriptor* = proc(index: cuint): ptr Lv2Descriptor {.cdecl.} + lv2LibDescriptor* = proc(bundle_path: cstring, features: ptr UncheckedArray[ptr Lv2Feature]): LV2_Lib_Descriptor {.cdecl.}