falkTX / Carla

Audio plugin host
https://kx.studio/carla
1.62k stars 146 forks source link

Feedback loops? #1062

Open mxmilkiib opened 4 years ago

mxmilkiib commented 4 years ago

As mentioned here https://github.com/ryukau/LV2Plugins/issues/3#issuecomment-602227626

falkTX commented 4 years ago

Good question. The internal patchbay has it disabled for good reasons (feedback loops are often a sign that something is wrong). It is not something that I will handle for this release anyway.

We can use this ticket for the conversation around feedback loops.

ryukau commented 4 years ago

I think it's great to have feedback loop with at most 1 sample delay, which is convenient for prototyping chorus, reverb, etc. But I'm not sure if it's possible with current CVPort specification.

Excerpt from LV2 CVPort specification:

Ports of this type have the same buffer format as an lv2:AudioPort, ...

Currently, plugin receives a CV input as a buffer rather than a sample or a frame. Which implies that host can't make any feedback loop without adding a delay of at least the size of buffer.

falkTX commented 4 years ago

But you cannot have that in a way that is not overly expensive (in terms of CPU) Regular plugins are meant to be used at a somewhat constant block size, the lower that gets, the heavier the project becomes. There are very little systems able to run audio at even 64 frames

ryukau commented 4 years ago

I agree that it's not realistic to reduce buffer size to 1 sample. I was thinking about completely different processing mode for CV plugins.

An idea is to concatenate CV part of audio graph to behave like non-CV plugins.

For example consider following graph:

        +<- CV_filter --+
        |               |
Synth ->+-- CV_delay -->+-> output

We somehow detect CV part of graph with some clever algorithm:

        +<- CV_filter --+
        |               |
      ->+-- CV_delay -->+->

Then compose a function (or class) like this:

float feedback = 0;

function cv_process(inBuffer, outBuffer, frames) {
  for (int i = 0; i < frames; ++i) {
    float sig = CV_delay.process(inBuffer[i] + feedback);
    feedback = CV_filter.process(sig);
    outBuffer[i] = sig;
  }
}

At this point, host can call cv_process like other non-CV plugins.


SuperCollider is a working example which can make 1 sample delay feedback. They have plugin format called UGen, and it's possible to make feedback loop with UGen.