Add nimble tasks and example 'amp' plugin
Signed-off-by: Christopher Arndt <chris@chrisarndt.de>
This commit is contained in:
		
							parent
							
								
									95100a0f03
								
							
						
					
					
						commit
						2f00720d2b
					
				
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
			
		||||
nimble.paths
 | 
			
		||||
*.so
 | 
			
		||||
*.dll
 | 
			
		||||
/.lv2/
 | 
			
		||||
							
								
								
									
										59
									
								
								examples/amp.lv2/amp.ttl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								examples/amp.lv2/amp.ttl
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,59 @@
 | 
			
		||||
@prefix bufs: <http://lv2plug.in/ns/ext/buf-size#> .
 | 
			
		||||
@prefix doap: <http://usefulinc.com/ns/doap#> .
 | 
			
		||||
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
 | 
			
		||||
@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
 | 
			
		||||
@prefix opts: <http://lv2plug.in/ns/ext/options#> .
 | 
			
		||||
@prefix params: <http://lv2plug.in/ns/ext/parameters#> .
 | 
			
		||||
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 | 
			
		||||
@prefix unit: <http://lv2plug.in/ns/extensions/units#> .
 | 
			
		||||
 | 
			
		||||
<urn:nymph:examples:amp>
 | 
			
		||||
    a lv2:Plugin, lv2:AmplifierPlugin , doap:Project ;
 | 
			
		||||
 | 
			
		||||
    lv2:optionalFeature lv2:hardRTCapable , bufs:boundedBlockLength , opts:options ;
 | 
			
		||||
 | 
			
		||||
    lv2:requiredFeature <http://lv2plug.in/ns/ext/urid#map> ;
 | 
			
		||||
 | 
			
		||||
    opts:supportedOption bufs:nominalBlockLength ,
 | 
			
		||||
                         bufs:maxBlockLength ,
 | 
			
		||||
                         params:sampleRate ;
 | 
			
		||||
 | 
			
		||||
    lv2:port [
 | 
			
		||||
        a lv2:InputPort, lv2:AudioPort ;
 | 
			
		||||
        lv2:index 0 ;
 | 
			
		||||
        lv2:name "Audio In" ;
 | 
			
		||||
        lv2:symbol "in" ;
 | 
			
		||||
    ],
 | 
			
		||||
    [
 | 
			
		||||
        a lv2:OutputPort, lv2:AudioPort ;
 | 
			
		||||
        lv2:index 1 ;
 | 
			
		||||
        lv2:name "Audio Out" ;
 | 
			
		||||
        lv2:symbol "out" ;
 | 
			
		||||
    ],
 | 
			
		||||
    [
 | 
			
		||||
        a lv2:InputPort, lv2:ControlPort ;
 | 
			
		||||
        lv2:index 2 ;
 | 
			
		||||
        lv2:name "Gain" ;
 | 
			
		||||
        lv2:symbol "gain" ;
 | 
			
		||||
        lv2:default 0.0 ;
 | 
			
		||||
        lv2:minimum -90.0 ;
 | 
			
		||||
        lv2:maximum 20.0 ;
 | 
			
		||||
        unit:unit unit:db ;
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    rdfs:comment """
 | 
			
		||||
A simple amplifier / attenuator.
 | 
			
		||||
""" ;
 | 
			
		||||
 | 
			
		||||
    doap:name "nymph example amp" ;
 | 
			
		||||
    doap:license <https://spdx.org/licenses/MIT> ;
 | 
			
		||||
 | 
			
		||||
    doap:maintainer [
 | 
			
		||||
        foaf:name "Christopher Arndt" ;
 | 
			
		||||
        foaf:mbox <mailto:info@chrisarndt.de> ;
 | 
			
		||||
        foaf:homepage <https://gitlab.com/SpotlightKid/nymph> ;
 | 
			
		||||
    ] ;
 | 
			
		||||
 | 
			
		||||
    lv2:microVersion 0 ;
 | 
			
		||||
    lv2:minorVersion 1 .
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										8
									
								
								examples/amp.lv2/manifest.ttl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								examples/amp.lv2/manifest.ttl
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
			
		||||
@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
 | 
			
		||||
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 | 
			
		||||
 | 
			
		||||
<urn:nymph:examples:amp>
 | 
			
		||||
    a lv2:Plugin ;
 | 
			
		||||
    lv2:binary <libamp.so> ;
 | 
			
		||||
    rdfs:seeAlso <amp.ttl> .
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										82
									
								
								examples/amp.nim
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								examples/amp.nim
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,82 @@
 | 
			
		||||
import std/math
 | 
			
		||||
import nymph
 | 
			
		||||
 | 
			
		||||
const PluginUri = "urn:nymph:examples:amp"
 | 
			
		||||
 | 
			
		||||
type
 | 
			
		||||
  CSample = cfloat
 | 
			
		||||
  CSamples = UncheckedArray[CSample]
 | 
			
		||||
 | 
			
		||||
  PortIndex = enum
 | 
			
		||||
    INPUT = 0,
 | 
			
		||||
    OUTPUT = 1,
 | 
			
		||||
    GAIN = 2
 | 
			
		||||
 | 
			
		||||
  Amp = object
 | 
			
		||||
    input: ptr CSamples
 | 
			
		||||
    output: ptr CSamples
 | 
			
		||||
    gain: ptr cfloat
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template db2coeff(db: cfloat): cfloat =
 | 
			
		||||
  pow(10.0, db / 20.0)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc instantiate(descriptor: ptr Lv2Descriptor; sampleRate: cdouble;
 | 
			
		||||
                 bundlePath: cstring; features: ptr ptr Lv2Feature):
 | 
			
		||||
                 Lv2Handle {.cdecl.} =
 | 
			
		||||
  return createShared(Amp)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc connectPort(instance: Lv2Handle; port: cuint;
 | 
			
		||||
                 dataLocation: pointer) {.cdecl.} =
 | 
			
		||||
  let amp = cast[ptr Amp](instance)
 | 
			
		||||
  case cast[PortIndex](port)
 | 
			
		||||
  of INPUT:
 | 
			
		||||
    amp.input = cast[ptr CSamples](dataLocation)
 | 
			
		||||
  of OUTPUT:
 | 
			
		||||
    amp.output = cast[ptr CSamples](dataLocation)
 | 
			
		||||
  of GAIN:
 | 
			
		||||
    amp.gain = cast[ptr cfloat](dataLocation)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc activate(instance: Lv2Handle) {.cdecl.} =
 | 
			
		||||
  discard
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc run(instance: Lv2Handle; nSamples: cuint) {.cdecl.} =
 | 
			
		||||
  let gain = cast[ptr Amp](instance)
 | 
			
		||||
  for pos in 0 ..< nSamples:
 | 
			
		||||
    gain.output[pos] = gain.input[pos] * db2coeff(gain.gain[])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc deactivate(instance: Lv2Handle) {.cdecl.} =
 | 
			
		||||
  discard
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc cleanup(instance: Lv2Handle) {.cdecl.} =
 | 
			
		||||
  freeShared(cast[ptr Amp](instance))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc extensionData(uri: cstring): pointer {.cdecl.} =
 | 
			
		||||
  return nil
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc NimMain() {.cdecl, importc.}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc lv2Descriptor(index: cuint): ptr Lv2Descriptor {.
 | 
			
		||||
                   cdecl, exportc, dynlib, extern: "lv2_descriptor".} =
 | 
			
		||||
  NimMain()
 | 
			
		||||
 | 
			
		||||
  if index == 0:
 | 
			
		||||
    result = createShared(Lv2Descriptor)
 | 
			
		||||
    result.uri = cstring(PluginUri)
 | 
			
		||||
    result.instantiate = instantiate
 | 
			
		||||
    result.connectPort = connectPort
 | 
			
		||||
    result.activate = activate
 | 
			
		||||
    result.run = run
 | 
			
		||||
    result.deactivate = deactivate
 | 
			
		||||
    result.cleanup = cleanup
 | 
			
		||||
    result.extensionData = extensionData
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								examples/config.nims
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								examples/config.nims
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
switch("path", "$projectDir/../src")
 | 
			
		||||
							
								
								
									
										116
									
								
								nymph.nimble
									
									
									
									
									
								
							
							
						
						
									
										116
									
								
								nymph.nimble
									
									
									
									
									
								
							@ -1,4 +1,5 @@
 | 
			
		||||
# Package
 | 
			
		||||
import std/strformat
 | 
			
		||||
 | 
			
		||||
version       = "0.1.0"
 | 
			
		||||
author        = "Christopher Arndt"
 | 
			
		||||
@ -10,3 +11,118 @@ srcDir        = "src"
 | 
			
		||||
# Dependencies
 | 
			
		||||
 | 
			
		||||
requires "nim >= 2.0"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Custom tasks
 | 
			
		||||
 | 
			
		||||
const examples = to_table({
 | 
			
		||||
    "amp": "urn:nymph:examples:amp"
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Parse task specific command line arguments into option switches and positional arguments
 | 
			
		||||
proc parseArgs(): tuple[options: seq[string], args: seq[string]] =
 | 
			
		||||
    for arg in commandLineParams:
 | 
			
		||||
        if arg[0] == '-':    # -d:foo or --define:foo
 | 
			
		||||
            result.options.add(arg)
 | 
			
		||||
        else:
 | 
			
		||||
            result.args.add(arg)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Show task environment (for debugging when writing nimble tasks)
 | 
			
		||||
proc showArgs() =
 | 
			
		||||
    echo "Command: ", getCommand()
 | 
			
		||||
    echo "ProjectName: ", projectName()
 | 
			
		||||
    echo "ProjectDir: ", projectDir()
 | 
			
		||||
    echo "ProjectPath: ", projectPath()
 | 
			
		||||
    echo "Task args: ", commandLineParams
 | 
			
		||||
 | 
			
		||||
    for i in 0..paramCount():
 | 
			
		||||
        echo &"Arg {i}: ", paramStr(i)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
task build_ex, "Build given example plugin":
 | 
			
		||||
    #showArgs()
 | 
			
		||||
    let (_, args) = parseArgs()
 | 
			
		||||
 | 
			
		||||
    if args.len == 0:
 | 
			
		||||
        echo "Usage: nimble build_ex <example name>"
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    let example = args[^1]
 | 
			
		||||
    let source = thisDir() & "/examples/" & example & ".nim"
 | 
			
		||||
    let bundle = thisDir() & "/examples/" & example & ".lv2"
 | 
			
		||||
    let dll = bundle & "/" & toDll(example)
 | 
			
		||||
 | 
			
		||||
    if fileExists(source):
 | 
			
		||||
        switch("app", "lib")
 | 
			
		||||
        switch("noMain", "on")
 | 
			
		||||
        switch("mm", "arc")
 | 
			
		||||
        switch("opt", "speed")
 | 
			
		||||
        switch("define", "release")
 | 
			
		||||
        switch("out", dll)
 | 
			
		||||
        setCommand("compile", source)
 | 
			
		||||
    else:
 | 
			
		||||
        echo &"Example '{example}' not found."
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
task lv2lint, "Run lv2lint check on given example plugin":
 | 
			
		||||
    let (_, args) = parseArgs()
 | 
			
		||||
 | 
			
		||||
    if args.len == 0:
 | 
			
		||||
        echo "Usage: nimble lv2lint <example name>"
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    let example = args[^1]
 | 
			
		||||
    let uri = examples.getOrDefault(example)
 | 
			
		||||
 | 
			
		||||
    if uri == "":
 | 
			
		||||
        echo &"Plugin URI for example '{example}' not set."
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    let examplesDir = thisDir() & "/examples"
 | 
			
		||||
    let bundle = examplesDir & "/" & example & ".lv2"
 | 
			
		||||
    let dll = bundle & "/" & toDll(example)
 | 
			
		||||
 | 
			
		||||
    if fileExists(dll):
 | 
			
		||||
        exec(&"lv2lint -s NimMain -I {bundle} \"{uri}\"")
 | 
			
		||||
    else:
 | 
			
		||||
        echo &"Example '{example}' shared library not found. Use task 'build_ex' to build it."
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
task lv2bm, "Run lv2bm benchmark on given example plugin":
 | 
			
		||||
    let (_, args) = parseArgs()
 | 
			
		||||
 | 
			
		||||
    if args.len == 0:
 | 
			
		||||
        echo "Usage: nimble lv2bm <example name>"
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    let example = args[^1]
 | 
			
		||||
    let uri = examples.getOrDefault(example)
 | 
			
		||||
 | 
			
		||||
    if uri == "":
 | 
			
		||||
        echo &"Plugin URI for example '{example}' not set."
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    let examplesDir = thisDir() & "/examples"
 | 
			
		||||
    let bundle = examplesDir & "/" & example & ".lv2"
 | 
			
		||||
    let dll = bundle & "/" & toDll(example)
 | 
			
		||||
 | 
			
		||||
    if fileExists(dll):
 | 
			
		||||
        let lv2_path = getEnv("LV2_PATH")
 | 
			
		||||
        let tempLv2Dir = thisDir() & "/.lv2"
 | 
			
		||||
        let bundleLink = tempLv2Dir & "/" & example & ".lv2"
 | 
			
		||||
 | 
			
		||||
        mkDir(tempLv2Dir)
 | 
			
		||||
        rmFile(bundleLink)
 | 
			
		||||
        exec(&"ln -s \"{bundle}\" \"{bundleLink}\"")
 | 
			
		||||
 | 
			
		||||
        if lv2_path == "":
 | 
			
		||||
            putEnv("LV2_PATH", tempLv2Dir)
 | 
			
		||||
        else:
 | 
			
		||||
            putEnv("LV2_PATH", tempLv2Dir & ":" & lv2_path)
 | 
			
		||||
 | 
			
		||||
        exec(&"lv2bm --full-test -i white \"{uri}\"")
 | 
			
		||||
    else:
 | 
			
		||||
        echo &"Example '{example}' shared library not found. Use task 'build_ex' to build it."
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,46 +1,32 @@
 | 
			
		||||
const LV2_CORE_URI* = "http://lv2plug.in/ns/lv2core"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
type Lv2Handle* = pointer
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
type Lv2Feature* = object
 | 
			
		||||
    uri*: cstring
 | 
			
		||||
    data*: pointer
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
type Lv2Descriptor* = object
 | 
			
		||||
    uri*: cstring
 | 
			
		||||
 | 
			
		||||
    instantiate* = proc(
 | 
			
		||||
        descriptor: ptr Lv2Descriptor,
 | 
			
		||||
        sampleRate: cdouble,
 | 
			
		||||
        bundlePath: cstring,
 | 
			
		||||
        features: ptr ptr Lv2Feature
 | 
			
		||||
    ): Lv2Handle {.cdecl.}
 | 
			
		||||
    instantiate*: proc(descriptor: ptr Lv2Descriptor, sampleRate: cdouble, bundlePath: cstring,
 | 
			
		||||
                       features: ptr ptr Lv2Feature): Lv2Handle {.cdecl.}
 | 
			
		||||
 | 
			
		||||
    connectPort*: proc(
 | 
			
		||||
        instance: Lv2Handle,
 | 
			
		||||
        port: cuint,
 | 
			
		||||
        dataLocation: pointer
 | 
			
		||||
    ) {.cdecl.}
 | 
			
		||||
    connectPort*: proc(instance: Lv2Handle, port: cuint, dataLocation: pointer) {.cdecl.}
 | 
			
		||||
 | 
			
		||||
    activate*: proc(
 | 
			
		||||
        instance: Lv2Handle
 | 
			
		||||
    ) {.cdecl.}
 | 
			
		||||
    activate*: proc(instance: Lv2Handle) {.cdecl.}
 | 
			
		||||
 | 
			
		||||
    run*: proc(
 | 
			
		||||
        instance: Lv2Handle,
 | 
			
		||||
        sampleCount: cuint
 | 
			
		||||
    ) {.cdecl.}
 | 
			
		||||
    run*: proc(instance: Lv2Handle, sampleCount: cuint) {.cdecl.}
 | 
			
		||||
 | 
			
		||||
    deactivate*: proc(
 | 
			
		||||
        instance: Lv2Handle
 | 
			
		||||
    ) {.cdecl.}
 | 
			
		||||
    deactivate*: proc(instance: Lv2Handle) {.cdecl.}
 | 
			
		||||
 | 
			
		||||
    cleanup*: proc(
 | 
			
		||||
        instance: Lv2Handle
 | 
			
		||||
    ) {.cdecl.}
 | 
			
		||||
    cleanup*: proc(instance: Lv2Handle) {.cdecl.}
 | 
			
		||||
 | 
			
		||||
    extensionData*: proc(uri: cstring): pointer {.cdecl.}
 | 
			
		||||
 | 
			
		||||
    extensionData*: proc(
 | 
			
		||||
        uri: cstring
 | 
			
		||||
    ): pointer {.cdecl.}
 | 
			
		||||
 | 
			
		||||
type lv2Descriptor* = proc(index: cuint): ptr Lv2Descriptor {.cdecl.}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1 +1,3 @@
 | 
			
		||||
switch("path", "$projectDir/../src")
 | 
			
		||||
switch("path", "$projectDir/../src")
 | 
			
		||||
switch("warning[BareExcept]", "off")
 | 
			
		||||
switch("warning[UnusedImport]", "off")
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user