Cabbage Logo
Back to Cabbage Site

Portk Output Latency

Hullo! I’ve been working on a synthesizer plugin and have run into some latency issues when using portk’s to smooth my knobs. For most of the controls it isn’t a problem to remove this smoothing, but for ADSR values this smoothing is helpful and keeps the synth from making zipper noise when adjusting these variables. I put together a simple instrument allowing the user to toggle on and off the portk’s. As you can see in these pictures, when portk is applied with porttime of 1ms there is 55ms of latency between note-on and sound output, whereas without portk, latency is only 1.5ms. Ableton Live shows the plugin to have 1.5ms of latency.

With portk:

Without portk:

I’m curious if anyone has advice on other methods of k-rate smoothing without this latency, or any reason as to why this much latency occurs. Attached is the demo synth if anyone’s interested. Thank you!

Quartz Portk Delay Demo.csd.zip (911 Bytes)

I’m not too familiar with portk and how it works internally, but smoothing i-rate envelope parameters is futile. If you are getting zipper noise from an madsr then there is something else afoot. Maybe you can post a simple example of an instrument that creates this zipper noise and we can take a look?

Sure, here’s that same instrument:

instr 1
katk chnget “attack1”
kdec chnget “decay1”
ksus chnget “sustain1”
krel chnget “release1”
if chnget:k(“tog”) == 0 then
kporttime = 0.001
katk portk katk, kporttime
kdec portk kdec, kporttime
ksus portk ksus, kporttime
krel portk krel, kporttime
endif
icps = p4
iamp = .5
kcps = k(icps)
kchanged = katk + kdec + ksus + krel
kreinit changed kchanged
if kreinit==1 then
reinit RESTART
endif
RESTART:
aenv mxadsr i(katk), i(kdec), i(ksus), i(krel)
aosc foscil iamp*aenv, kcps, 1, 0, 0, 1
outs aosc, aosc
endin

When portk is used and ADSR values are tweaked, playback stops (due to the reinit message) and doesn’t resume until the variable isn’t moving. Without portk the playback stops and starts constantly as the variable moves. Here’s a video demonstrating that.

My initial concerns remain, why are you casting k-rate variables as i-rate when you can simply do:

iatk chnget “attack1”
idec chnget “decay1”
isus chnget “sustain1”
irel chnget “release1”
aenv mxadsr iatk, idec, isus, irel

This way you don’t need to do any smoothing/casting/etc. You see what I mean?

1 Like

Wow I can’t believe that was it. Thank you so much for your help!

1 Like