feat: add tiltfilter example
This commit is contained in:
		
							parent
							
								
									75f3ce03b3
								
							
						
					
					
						commit
						f001184fea
					
				@ -1,7 +1,7 @@
 | 
			
		||||
@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 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#> .
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
 | 
			
		||||
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 | 
			
		||||
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 | 
			
		||||
 | 
			
		||||
<urn:nymph:examples:amp>
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
 | 
			
		||||
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 | 
			
		||||
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 | 
			
		||||
 | 
			
		||||
<urn:nymph:examples:miditranspose>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
 | 
			
		||||
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 | 
			
		||||
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 | 
			
		||||
 | 
			
		||||
<urn:nymph:examples:multimode-filter>
 | 
			
		||||
<urn:nymph:examples:multimodefilter>
 | 
			
		||||
    a lv2:Plugin ;
 | 
			
		||||
    lv2:binary <libmultimodefilter.so> ;
 | 
			
		||||
    rdfs:seeAlso <multimodefilter.ttl> .
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,11 @@
 | 
			
		||||
@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 lv2: <http://lv2plug.in/ns/lv2core#> .
 | 
			
		||||
@prefix opts: <http://lv2plug.in/ns/ext/options#> .
 | 
			
		||||
@prefix params: <http://lv2plug.in/ns/ext/parameters#> .
 | 
			
		||||
@prefix props: <http://lv2plug.in/ns/ext/port-props#> .
 | 
			
		||||
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 | 
			
		||||
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 | 
			
		||||
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 | 
			
		||||
@prefix units: <http://lv2plug.in/ns/extensions/units#> .
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										8
									
								
								examples/tiltfilter.lv2/manifest.ttl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								examples/tiltfilter.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:tiltfilter>
 | 
			
		||||
    a lv2:Plugin ;
 | 
			
		||||
    lv2:binary <libtiltfilter.so> ;
 | 
			
		||||
    rdfs:seeAlso <tiltfilter.ttl> .
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										90
									
								
								examples/tiltfilter.lv2/tiltfilter.ttl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								examples/tiltfilter.lv2/tiltfilter.ttl
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,90 @@
 | 
			
		||||
@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 props: <http://lv2plug.in/ns/ext/port-props#> .
 | 
			
		||||
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 | 
			
		||||
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 | 
			
		||||
@prefix units: <http://lv2plug.in/ns/extensions/units#> .
 | 
			
		||||
 | 
			
		||||
<urn:nymph:examples:tiltfilter>
 | 
			
		||||
    a lv2:Plugin , lv2:FilterPlugin , doap:Project ;
 | 
			
		||||
 | 
			
		||||
    lv2:optionalFeature lv2:hardRTCapable , bufs:boundedBlockLength , opts:options ;
 | 
			
		||||
 | 
			
		||||
    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 "Cutoff" ;
 | 
			
		||||
        lv2:symbol "cutoff" ;
 | 
			
		||||
        lv2:default 10000.0 ;
 | 
			
		||||
        lv2:minimum 20.0 ;
 | 
			
		||||
        lv2:maximum 20000.0 ;
 | 
			
		||||
        units:unit units:hz ;
 | 
			
		||||
    ],
 | 
			
		||||
    [
 | 
			
		||||
        a lv2:InputPort, lv2:ControlPort ;
 | 
			
		||||
        lv2:index 3 ;
 | 
			
		||||
        lv2:name "Steepness" ;
 | 
			
		||||
        lv2:symbol "steepness" ;
 | 
			
		||||
        lv2:default 1.0 ;
 | 
			
		||||
        lv2:minimum 0.0 ;
 | 
			
		||||
        lv2:maximum 1.0 ;
 | 
			
		||||
    ],
 | 
			
		||||
    [
 | 
			
		||||
        a lv2:InputPort, lv2:ControlPort ;
 | 
			
		||||
        lv2:index 4 ;
 | 
			
		||||
        lv2:name "Filter mode" ;
 | 
			
		||||
        lv2:symbol "mode" ;
 | 
			
		||||
        lv2:default 0 ;
 | 
			
		||||
        lv2:minimum 0 ;
 | 
			
		||||
        lv2:maximum 2 ;
 | 
			
		||||
        lv2:portProperty lv2:enumeration, lv2:integer ;
 | 
			
		||||
        lv2:scalePoint [
 | 
			
		||||
            rdfs:label "Lowpass" ;
 | 
			
		||||
            rdf:value 0 ;
 | 
			
		||||
        ],
 | 
			
		||||
        [
 | 
			
		||||
            rdfs:label "Highpass" ;
 | 
			
		||||
            rdf:value 1 ;
 | 
			
		||||
        ],
 | 
			
		||||
        [
 | 
			
		||||
            rdfs:label "Bandpass" ;
 | 
			
		||||
            rdf:value 2;
 | 
			
		||||
        ] ;
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    rdfs:comment """
 | 
			
		||||
A tilt EQ audio filter.
 | 
			
		||||
""" ;
 | 
			
		||||
 | 
			
		||||
    doap:name "nymph tilt filter" ;
 | 
			
		||||
    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 .
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										165
									
								
								examples/tiltfilter.nim
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								examples/tiltfilter.nim
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,165 @@
 | 
			
		||||
##
 | 
			
		||||
## Tilt Filter
 | 
			
		||||
##
 | 
			
		||||
## Nim translation of this Rust implementation:
 | 
			
		||||
##
 | 
			
		||||
## https://github.com/ardura/Actuate/blob/main/src/fx/ArduraFilter.rs
 | 
			
		||||
##
 | 
			
		||||
## Inspired by https://www.musicdsp.org/en/latest/Filters/267-simple-tilt-equalizer.html
 | 
			
		||||
## Lowpass, Bandpass, Highpass based off tilt filter code
 | 
			
		||||
 | 
			
		||||
import math
 | 
			
		||||
 | 
			
		||||
const
 | 
			
		||||
    slopeNeg = -60.0
 | 
			
		||||
    amp = 6.0 / ln(2.0)
 | 
			
		||||
    denorm = pow(10.0, -30.0)
 | 
			
		||||
    minFreq = 20.0
 | 
			
		||||
    maxFreq = 20_000.0
 | 
			
		||||
 | 
			
		||||
type
 | 
			
		||||
    FilterMode* = enum
 | 
			
		||||
        fmLowPass, fmBandPass, fmHighPass
 | 
			
		||||
 | 
			
		||||
    TiltFilter* = object
 | 
			
		||||
        # Filter parameters
 | 
			
		||||
        sampleRate: float64
 | 
			
		||||
        centerFreq: float
 | 
			
		||||
        steepness: float
 | 
			
		||||
        mode: FilterMode
 | 
			
		||||
        # Filter tracking / internal
 | 
			
		||||
        needsUpdate: bool
 | 
			
		||||
        sampleRateX3: float64
 | 
			
		||||
        lowGain: float
 | 
			
		||||
        highGain: float
 | 
			
		||||
        a: float
 | 
			
		||||
        b: float
 | 
			
		||||
        lpOut: float
 | 
			
		||||
        # Band pass separate vars
 | 
			
		||||
        bandALow: float
 | 
			
		||||
        bandBLow: float
 | 
			
		||||
        bandOutLow: float
 | 
			
		||||
        bandAHigh: float
 | 
			
		||||
        bandBHigh: float
 | 
			
		||||
        bandOutHigh: float
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Super useful function to scale an sample 0-1 into other ranges
 | 
			
		||||
proc scaleRange(sample, minOutput, maxOutput: float): float =
 | 
			
		||||
    result = clamp(sample * (maxOutput - minOutput) + minOutput, minOutput, maxOutput)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc initTiltFilter*(centerFreq, steepness: float, mode: FilterMode = fmLowPass, sampleRate: float64 = 48_000.0): TiltFilter =
 | 
			
		||||
    let sampleRateX3 = 3.0 * sampleRate
 | 
			
		||||
 | 
			
		||||
    case mode:
 | 
			
		||||
        # These are the gains for the slopes when math happens later
 | 
			
		||||
        of fmLowPass:
 | 
			
		||||
            result.lowGain = exp(0.0 / amp) - 1.0
 | 
			
		||||
            result.highGain = exp(slopeNeg / amp) - 1.0
 | 
			
		||||
        of fmBandPass:
 | 
			
		||||
            result.lowGain = exp(0.0 / amp) - 1.0
 | 
			
		||||
            result.highGain = exp(slopeNeg / amp) - 1.0
 | 
			
		||||
        of fmHighPass:
 | 
			
		||||
            result.lowGain = exp(slopeNeg / amp) - 1.0
 | 
			
		||||
            result.highGain = exp(0.0 / amp) - 1.0
 | 
			
		||||
 | 
			
		||||
    let omega = 2.0 * PI * centerFreq
 | 
			
		||||
    let n = 1.0 / (scaleRange(steepness, 0.98, 1.2) * (sampleRateX3 + omega))
 | 
			
		||||
    result.a = 2.0 * omega * n
 | 
			
		||||
    result.bandALow = result.a
 | 
			
		||||
    result.bandAHigh = result.a
 | 
			
		||||
    result.b = (sampleRateX3 - omega) * n
 | 
			
		||||
    result.bandBLow = result.b
 | 
			
		||||
    result.bandBHigh = result.b
 | 
			
		||||
    result.lpOut = 0.0
 | 
			
		||||
    result.bandOutLow = 0.0
 | 
			
		||||
    result.bandOutHigh = 0.0
 | 
			
		||||
    result.centerFreq = centerFreq
 | 
			
		||||
    result.sampleRateX3 = sampleRateX3
 | 
			
		||||
    result.steepness = steepness
 | 
			
		||||
    result.sampleRate = sampleRate
 | 
			
		||||
    result.mode = mode
 | 
			
		||||
    result.needsUpdate = true
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc setMode*(self: var TiltFilter, mode: FilterMode) =
 | 
			
		||||
    if mode != self.mode:
 | 
			
		||||
        self.mode = mode
 | 
			
		||||
        self.needsUpdate = true
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc setCenterFreq*(self: var TiltFilter, value: float) =
 | 
			
		||||
    let freq = value.clamp(minFreq, maxFreq)
 | 
			
		||||
 | 
			
		||||
    if freq != self.centerFreq:
 | 
			
		||||
        self.centerFreq = freq
 | 
			
		||||
        self.needsUpdate = true
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc setSteepness*(self: var TiltFilter, value: float) =
 | 
			
		||||
    let steepness = value.clamp(0.0, 1.0)
 | 
			
		||||
 | 
			
		||||
    if steepness != self.steepness:
 | 
			
		||||
        self.steepness = steepness
 | 
			
		||||
        self.needsUpdate = true
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc setSampleRate*(self: var TiltFilter, sampleRate: float) =
 | 
			
		||||
    if sampleRate != self.sampleRate:
 | 
			
		||||
        self.sampleRate = sampleRate
 | 
			
		||||
        self.sampleRateX3 = self.sampleRate * 3.0
 | 
			
		||||
        self.needsUpdate = true
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc reset*(self: var TiltFilter) =
 | 
			
		||||
    discard
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc update*(self: var TiltFilter) =
 | 
			
		||||
    if self.needsUpdate:
 | 
			
		||||
        case self.mode:
 | 
			
		||||
            of fmLowPass:
 | 
			
		||||
                let omega = 2.0 * PI * self.centerFreq
 | 
			
		||||
                let n = 1.0 / (scaleRange(self.steepness, 0.98, 1.2) * (self.sample_rate_x3 + omega))
 | 
			
		||||
                self.b = (self.sampleRateX3 - omega) * n
 | 
			
		||||
                self.lowGain = exp(0.0 / amp) - 1.0
 | 
			
		||||
                self.highGain = exp(slopeNeg / amp) - 1.0
 | 
			
		||||
            of fmBandPass:
 | 
			
		||||
                let width = self.steepness * self.steepness * 500.0
 | 
			
		||||
 | 
			
		||||
                let lowOmega = 2.0 * PI * (self.centerFreq - width).clamp(20.0, 16_000.0)
 | 
			
		||||
                let lowN = 1.0 / (scaleRange(self.steepness, 0.98, 1.2) * (self.sampleRateX3 + lowOmega))
 | 
			
		||||
                self.bandALow = 2.0 * lowOmega * lowN
 | 
			
		||||
                self.bandBLow = (self.sampleRateX3 - lowOmega) * lowN
 | 
			
		||||
 | 
			
		||||
                let highOmega = 2.0 * PI * (self.centerFreq + width).clamp(20.0, 16_000.0);
 | 
			
		||||
                let highN = 1.0 / (scaleRange(self.steepness, 0.98, 1.2) * (self.sampleRateX3 + highOmega))
 | 
			
		||||
                self.bandAHigh = 2.0 * highOmega * highN
 | 
			
		||||
                self.bandBHigh = (self.sampleRateX3 - highOmega) * highN
 | 
			
		||||
 | 
			
		||||
                self.lowGain = exp(0.0 / amp) - 1.0
 | 
			
		||||
                self.highGain = exp(slopeNeg / amp) - 1.0
 | 
			
		||||
            of fmHighPass:
 | 
			
		||||
                let omega = 2.0 * PI * self.centerFreq
 | 
			
		||||
                let n = 1.0 / (scaleRange(self.steepness, 0.98, 1.2) * (self.sampleRateX3 + omega))
 | 
			
		||||
                self.a = 2.0 * omega * n
 | 
			
		||||
                self.b = (self.sampleRateX3 - omega) * n
 | 
			
		||||
                self.lowGain = exp(slopeNeg / amp) - 1.0
 | 
			
		||||
                self.highGain = exp(0.0 / amp) - 1.0
 | 
			
		||||
 | 
			
		||||
        self.needsUpdate = false
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##
 | 
			
		||||
## Process the input sample using the tilt filter
 | 
			
		||||
##
 | 
			
		||||
proc process*(self: var TiltFilter, sample: float): float =
 | 
			
		||||
    if self.mode == fmBandPass:
 | 
			
		||||
        self.bandOutLow = self.bandALow * sample + self.bandBLow * self.bandOutLow
 | 
			
		||||
        let temp = sample + self.highGain * self.bandOutLow + self.lowGain * (sample - self.bandOutLow)
 | 
			
		||||
        self.bandOutHigh = self.bandAHigh * temp + self.bandBHigh * self.bandOutHigh
 | 
			
		||||
        result = temp + self.lowGain * self.bandOutHigh + self.highGain * (temp - self.bandOutHigh) + denorm
 | 
			
		||||
    else:
 | 
			
		||||
        self.lpOut = self.a * sample + self.b * self.lpOut;
 | 
			
		||||
        result = sample + self.lowGain * self.lpOut + self.highGain * (sample - self.lpOut) + denorm
 | 
			
		||||
							
								
								
									
										104
									
								
								examples/tiltfilter_plugin.nim
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								examples/tiltfilter_plugin.nim
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,104 @@
 | 
			
		||||
## A tilt EQ / filter LV2 plugin
 | 
			
		||||
 | 
			
		||||
import nymph
 | 
			
		||||
 | 
			
		||||
import paramsmooth
 | 
			
		||||
import tiltfilter
 | 
			
		||||
 | 
			
		||||
const
 | 
			
		||||
    PluginUri = "urn:nymph:examples:tiltfilter"
 | 
			
		||||
    minFreq = 20.0
 | 
			
		||||
    maxFreq = 20_000.0
 | 
			
		||||
 | 
			
		||||
type
 | 
			
		||||
    SampleBuffer = UncheckedArray[cfloat]
 | 
			
		||||
 | 
			
		||||
    PluginPort {.pure.} = enum
 | 
			
		||||
        Input, Output, Frequency, Steepness, Mode
 | 
			
		||||
 | 
			
		||||
    TiltFilterPlugin = object
 | 
			
		||||
        input: ptr SampleBuffer
 | 
			
		||||
        output: ptr SampleBuffer
 | 
			
		||||
        freq: ptr cfloat
 | 
			
		||||
        steepness: ptr cfloat
 | 
			
		||||
        mode: ptr cfloat
 | 
			
		||||
        flt: TiltFilter
 | 
			
		||||
        smoothFreq: ParamSmooth
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc instantiate(descriptor: ptr Lv2Descriptor; sampleRate: cdouble;
 | 
			
		||||
                 bundlePath: cstring; features: ptr UncheckedArray[ptr Lv2Feature]):
 | 
			
		||||
                 Lv2Handle {.cdecl.} =
 | 
			
		||||
    try:
 | 
			
		||||
        let plug = createShared(TiltFilterPlugin)
 | 
			
		||||
        plug.flt = initTiltFilter(10_000.0, 1.0, fmLowPass, sampleRate)
 | 
			
		||||
        plug.smoothFreq = initParamSmooth(20.0, sampleRate)
 | 
			
		||||
        return cast[Lv2Handle](plug)
 | 
			
		||||
    except OutOfMemDefect:
 | 
			
		||||
        return nil
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc connectPort(instance: Lv2Handle; port: cuint;
 | 
			
		||||
                 dataLocation: pointer) {.cdecl.} =
 | 
			
		||||
    let plug = cast[ptr TiltFilterPlugin](instance)
 | 
			
		||||
    case cast[PluginPort](port)
 | 
			
		||||
    of PluginPort.Input:
 | 
			
		||||
        plug.input = cast[ptr SampleBuffer](dataLocation)
 | 
			
		||||
    of PluginPort.Output:
 | 
			
		||||
        plug.output = cast[ptr SampleBuffer](dataLocation)
 | 
			
		||||
    of PluginPort.Frequency:
 | 
			
		||||
        plug.freq = cast[ptr cfloat](dataLocation)
 | 
			
		||||
    of PluginPort.Steepness:
 | 
			
		||||
        plug.steepness = cast[ptr cfloat](dataLocation)
 | 
			
		||||
    of PluginPort.Mode:
 | 
			
		||||
        plug.mode = cast[ptr cfloat](dataLocation)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc activate(instance: Lv2Handle) {.cdecl.} =
 | 
			
		||||
    let plug = cast[ptr TiltFilterPlugin](instance)
 | 
			
		||||
    plug.flt.reset()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc run(instance: Lv2Handle; nSamples: cuint) {.cdecl.} =
 | 
			
		||||
    let plug = cast[ptr TiltFilterPlugin](instance)
 | 
			
		||||
    let freq = plug.freq[].clamp(minFreq, maxFreq)
 | 
			
		||||
 | 
			
		||||
    plug.flt.setMode(plug.mode[].clamp(0.0, 2.0).FilterMode)
 | 
			
		||||
    plug.flt.setSteepness(plug.steepness[])
 | 
			
		||||
 | 
			
		||||
    for pos in 0 ..< nSamples:
 | 
			
		||||
        plug.flt.setCenterFreq(plug.smoothFreq.process(freq))
 | 
			
		||||
        plug.flt.update()
 | 
			
		||||
        plug.output[pos] = plug.flt.process(plug.input[pos])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc deactivate(instance: Lv2Handle) {.cdecl.} =
 | 
			
		||||
    discard
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proc cleanup(instance: Lv2Handle) {.cdecl.} =
 | 
			
		||||
    freeShared(cast[ptr TiltFilterPlugin](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
 | 
			
		||||
 | 
			
		||||
@ -26,7 +26,8 @@ type Example = tuple
 | 
			
		||||
const examples = to_table({
 | 
			
		||||
    "amp": "urn:nymph:examples:amp",
 | 
			
		||||
    "miditranspose": "urn:nymph:examples:miditranspose",
 | 
			
		||||
    "multimodefilter": "urn:nymph:examples:multimode-filter",
 | 
			
		||||
    "multimodefilter": "urn:nymph:examples:multimodefilter",
 | 
			
		||||
    "tiltfilter": "urn:nymph:examples:tiltfilter",
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user