# New to cabbage, used csound ages ago

**URL:** <https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379>\
**Category:** Csound Noobs\
**Created:** [9 June 2024 22:54 UTC](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379 "2024-06-09T22:54:09Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Bryan\_T](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/bryan_t/32/5680_2.png) [@Bryan\_T](https://forum.cabbageaudio.com/u/Bryan_T)\
**Post date:** [9 June 2024 22:54 UTC](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379/1 "2024-06-09T22:54:09Z")

</div>

I just learned about Cabbage today and am considering diving in for developing a looping audio plugin. I used CSound decades ago for synthesis, but audio processing will be new to me. Wish me luck!

---

<div class="post-metadata">

**Author:** ![Bryan\_T](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/bryan_t/32/5680_2.png) [@Bryan\_T](https://forum.cabbageaudio.com/u/Bryan_T)\
**Post date:** [10 June 2024 04:00 UTC](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379/2 "2024-06-10T04:00:25Z")

</div>

I was trying to get this working, but using live audio: _ **05D08\_custom\_delay\_line.csd** _ from [https://flossmanual.csound.com/sound-modification/delay-and-feedback](https://flossmanual.csound.com/sound-modification/delay-and-feedback)

My version using live audio sounds like the sample rate is reduced on the delayed signal. Is that because the array isn’t processing at audio rates?

I can swap it out for one of the canned delay functions, but I’d like to understand what’s going wrong. Thanks!

---

<div class="post-metadata">

**Author:** ![ST\_Music](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/st_music/32/4405_2.png) [@ST\_Music](https://forum.cabbageaudio.com/u/ST_Music)\
**Post date:** [10 June 2024 07:13 UTC](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379/3 "2024-06-10T07:13:55Z")

</div>

Hi Bryan. Without seeing your code there’s no way to tell what’s going on but the delay should sound just like the live input. There is no audio sample rate reduction occurring.

---

<div class="post-metadata">

**Author:** ![Bryan\_T](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/bryan_t/32/5680_2.png) [@Bryan\_T](https://forum.cabbageaudio.com/u/Bryan_T)\
**Post date:** [10 June 2024 08:34 UTC](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379/4 "2024-06-10T08:34:54Z")

</div>

In the version that sounds like the sample rate is reduced “ksmps” is set to 32. When I reduce it to 1, then it sounds normal.

Bryan

```
<Cabbage>
form caption("Untitled") size(400, 300), guiMode("queue") pluginId("def1")
rslider bounds(296, 162, 100, 100), channel("gain"), range(0, 1, 0, 1, .01), text("Gain"), trackerColour("lime"), outlineColour(0, 0, 0, 50), textColour("black")
rslider bounds(80, 80, 100, 100), channel("input"), range(0, 1, 0, 1, .01), text("Input"), trackerColour("lime"), outlineColour(0, 0, 0, 50), textColour("black")
rslider bounds(162, 80, 100, 100), channel("feedback"), range(0, 1, 0, 1, .01), text("Feedback"), trackerColour("lime"), outlineColour(0, 0, 0, 50), textColour("black")

</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d
</CsOptions>
<CsInstruments>
; Initialize the global variables. 
ksmps = 1
nchnls = 2
0dbfs = 1

instr 1
kInput cabbageGetValue "input"
kGain cabbageGetValue "gain"
kFeedback cabbageGetValue "feedback"

a1 inch 1
a2 inch 2

;; 4 second delay
  idel_size = (4) * sr
  kdelay_line[] init idel_size
  kread_ptr init 1
  kwrite_ptr init 0

  kindx = 0
  while (kindx < ksmps) do
    kdelay_line[kwrite_ptr] = kInput*a1 + kFeedback*kdelay_line[kread_ptr]
    adel[kindx] = kdelay_line[kread_ptr]

    kwrite_ptr = (kwrite_ptr + 1) % idel_size
    kread_ptr = (kread_ptr + 1) % idel_size

    kindx += 1
  od

outs a1*kGain + adel*kGain, a1*kGain + adel*kGain
endin

</CsInstruments>
<CsScore>
;causes Csound to run for about 7000 years...
f0 z
;starts instrument 1 and runs it for a week
i1 0 [60*60*24*7] 
</CsScore>
</CsoundSynthesizer>
```

---

<div class="post-metadata">

**Author:** ![rorywalsh](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/rorywalsh/32/165_2.png) [@rorywalsh](https://forum.cabbageaudio.com/u/rorywalsh)\
**Post date:** [10 June 2024 08:49 UTC](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379/5 "2024-06-10T08:49:33Z")

</div>

You’re using k-rate arrays to hold audio samples. You’ve already worked this out but setting `ksmps` to 1 will work as each k sample will represent one audio sample. But if `ksmps` is anything but 1, you will only be writing every ksmps sample to your array. The typical approach in this context is to use a UDO to handle the processing as, you can set a local ksmps there using [setksmps](https://csound.com/docs/manual/setksmps.html). This way your UDO will run at a lower ksmps than your orchestra.

FWIW, you can leave ksmps set to 1 in your orchestra too, but you might find it eats up a little too much CPU.

---

<div class="post-metadata">

**Author:** ![Bryan\_T](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/bryan_t/32/5680_2.png) [@Bryan\_T](https://forum.cabbageaudio.com/u/Bryan_T)\
**Post date:** [10 June 2024 09:00 UTC](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379/6 "2024-06-10T09:00:34Z")

</div>

I was also able to get it to sound “normal” with this approach in the while loop (ksmps set back to 32):

`kdelay_line[kwrite_ptr] = kInput*a1[kindx] + kFeedback*kdelay_line[kread_ptr]`

I’m having an issue now where Logic Pro doesn’t load my AU effect. No idea if that is related or a different user error.

---

<div class="post-metadata">

**Author:** ![ST\_Music](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/st_music/32/4405_2.png) [@ST\_Music](https://forum.cabbageaudio.com/u/ST_Music)\
**Post date:** [10 June 2024 10:05 UTC](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379/7 "2024-06-10T10:05:04Z")

</div>

I can’t use inch so no way for me to directly compare. However, take this code for example:

```
<CsoundSynthesizer>
<CsOptions>
-odac
; -o 0_array_delay.wav
</CsOptions>
<CsInstruments>
sr = 44100
ksmps = 32
nchnls = 2
0dbfs = 1

instr CustomDelayLine

  ;; 0.5 second delay
  idel_size = 0.5 * sr
  kdelay_line[] init idel_size
  kread_ptr init 1
  kwrite_ptr init 1 ; 0

  aenv = expseg:a(.001, .004, 1, .2, .001)
  asig = noise(.8, 0) * aenv

  kindx = 0
  while (kindx < ksmps) do
    kdelay_line[kwrite_ptr] = asig[kindx]
    adel[kindx] = kdelay_line[kread_ptr]

    kwrite_ptr = (kwrite_ptr + 1) % idel_size
    kread_ptr = (kread_ptr + 1) % idel_size

    kindx += 1
  od
printk2 kindx
  out(asig, adel)
endin

</CsInstruments>
<CsScore>
i1 0 1
</CsScore>
</CsoundSynthesizer>
;example by Steven Yi

```

In this case, and perhaps Rory you can correct me if I’m mistaken, the k-rate arrays are still still sample accurate as stated in the FLOSS manual (“an advanced insight into sample-by-sample processing in Csound”). I believe it is incorrect to suggest only every ksmps one audio sample is written to the array. It appears that every 1 ksmps cycle 32 audio samples are in fact written to the array.

You’ll see in the code that in one channel (L) is the direct audio. In the other channel is the array output. I used white noise to demonstrate. Viewed in a spectrum analyzer, there is no frequency loss. And when zoomed in the array output is literally sample accurate to the original white noise (see pic). So I can’t understand why you might experience an issue. Not sure what I might be missing here as in the case that if at kspms = 32 only one audio sample was written then that would be visible - there would be visible stepping and it would no longer be sample accurate as it appears to be.

 ![comparison](https://forum.cabbageaudio.com/uploads/default/original/2X/f/f69d6ca8480ed3882a40d51d2db8a5cb4da05b92.jpeg)

---

<div class="post-metadata">

**Author:** ![rorywalsh](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/rorywalsh/32/165_2.png) [@rorywalsh](https://forum.cabbageaudio.com/u/rorywalsh)\
**Post date:** [10 June 2024 10:12 UTC](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379/8 "2024-06-10T10:12:52Z")

</div>

you’re right @ST_Music, my initial reaction is always don’t mix k-rate and a-rate, but in this case, considering the loop is happening inline it should work fine.

@Bryan_T you need to codesign your plugin to get it to work in Logic. There is a lot of info about this on the forum.

---

<div class="post-metadata">

**Author:** ![rorywalsh](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/rorywalsh/32/165_2.png) [@rorywalsh](https://forum.cabbageaudio.com/u/rorywalsh)\
**Post date:** [10 June 2024 10:24 UTC](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379/9 "2024-06-10T10:24:18Z")

</div>

I think the fix @Bryan_T posted now does the same thing as yours @ST_Music. This was the problem line:

```
kdelay_line[kwrite_ptr] = kInput*a1 + kFeedback*kdelay_line[kread_ptr]

```

As I understand it, `a1` will also return the first sample in the vector. As you’ve both shown, if you want to access samples within the vector in a k-rate loop, you have to use the array syntax on the a-rate variable. Or? I’m just trying to get this clear in my own head 🤣

---

<div class="post-metadata">

**Author:** ![ST\_Music](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/st_music/32/4405_2.png) [@ST\_Music](https://forum.cabbageaudio.com/u/ST_Music)\
**Post date:** [10 June 2024 10:36 UTC](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379/10 "2024-06-10T10:36:09Z")

</div>

@rorywalsh To be honest, I’m not sure this offers any benefit to simply using a delay opcode and, if one wants, feeding the signal back on itself (see FLOSS ex. 05D03\_delay\_feedback\_2.csd)

I’d be curious to know.

---

<div class="post-metadata">

**Author:** ![rorywalsh](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/rorywalsh/32/165_2.png) [@rorywalsh](https://forum.cabbageaudio.com/u/rorywalsh)\
**Post date:** [10 June 2024 10:41 UTC](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379/11 "2024-06-10T10:41:48Z")

</div>

I agree. Using a delay opcode would be simpler, and offer better performance. I guess building delays like this from first principles is a good way to understand how they work. That’s probably why it’s included in the FLOSS manual.

---

<div class="post-metadata">

**Author:** ![Bryan\_T](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/bryan_t/32/5680_2.png) [@Bryan\_T](https://forum.cabbageaudio.com/u/Bryan_T)\
**Post date:** [10 June 2024 14:01 UTC](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379/12 "2024-06-10T14:01:32Z")

</div>

Thanks for all of the discussion! I’m glad the error was simple and my fault.

I’m using this approach for a few reasons. It is closest to the methods in another book I have about plugin design in C++. And this is just the first step in what will be a complex looping plugin that is built on multiple delay lines. I suspect I’ll want access to the inner workings for filtering, changing direction/speed, and pulling out grains. But I’ll definitely keep the built-in delay opcodes in mind.

I’m not sure why my plug-in isn’t showing up in logic. I had no issues with an earlier version working. Probably user error as I figure out the workflow of exporting and adding to Logic.

Thanks!

---

<div class="post-metadata">

**Author:** ![Bryan\_T](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/bryan_t/32/5680_2.png) [@Bryan\_T](https://forum.cabbageaudio.com/u/Bryan_T)\
**Post date:** [10 June 2024 14:58 UTC](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379/13 "2024-06-10T14:58:35Z")

</div>

I figured out the issue in Logic. I hadn’t given the plugin a unique ID. Lesson learned.

Here is a quick improv I did in Logic with solo guitar and the simplest version of my looper: [https://on.soundcloud.com/tyNQs6QrnCZbmDZ28](https://on.soundcloud.com/tyNQs6QrnCZbmDZ28)

I’m beyond excited about the possibilities here. I learned about Cabbage yesterday and I’ve already created a working, musical tool that can be the basis for a much bigger project. So cool!

---

<div class="post-metadata">

**Author:** ![rorywalsh](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/rorywalsh/32/165_2.png) [@rorywalsh](https://forum.cabbageaudio.com/u/rorywalsh)\
**Post date:** [10 June 2024 15:21 UTC](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379/14 "2024-06-10T15:21:04Z")

</div>

Sounds very nice. The options are endless once you start creating your own plugins 🙂

---

<div class="post-metadata">

**Author:** ![Bryan\_T](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/bryan_t/32/5680_2.png) [@Bryan\_T](https://forum.cabbageaudio.com/u/Bryan_T)\
**Post date:** [10 June 2024 18:43 UTC](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379/15 "2024-06-10T18:43:57Z")

</div>

One version of what I’m hoping to do will have four (for example) delay lines of (potentially) different lengths. Should I plan to allocate the memory for these when the plug-in is launched? Basically, specify a maximum length and then truncate it based on user input? Or is there a more efficient way to think about it?

Related, I might want to “hide” the delay lines that aren’t used until they are needed. I could see doing that via the GUI (greying out controls that aren’t used, for example). But I could also see dynamically creating the delay lines and controls. The latter might not be feasible.

Thanks!

---

<div class="post-metadata">

**Author:** ![Bryan\_T](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/bryan_t/32/5680_2.png) [@Bryan\_T](https://forum.cabbageaudio.com/u/Bryan_T)\
**Post date:** [12 June 2024 06:42 UTC](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379/16 "2024-06-12T06:42:47Z")

</div>

The suggestion I got from chatgpt was to use two instruments. The first defines the effect a bit generically. The second creates/destroys instances of the effect. The cabbage stuff is pre-populated for the four instances, with some control over the appearance of the controls if the effect doesn’t exist.

Does that sound like it might work?

---

<div class="post-metadata">

**Author:** ![rorywalsh](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/rorywalsh/32/165_2.png) [@rorywalsh](https://forum.cabbageaudio.com/u/rorywalsh)\
**Post date:** [12 June 2024 08:15 UTC](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379/17 "2024-06-12T08:15:42Z")

</div>

Sounds like a reasonable plan. You just have to make sure each instance has its own unique memory resources. For example, if you are writing to function tables, you need to make sure each instance isn’t trying to read/write from the same one 👍

---

<div class="post-metadata">

**Author:** ![Bryan\_T](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/bryan_t/32/5680_2.png) [@Bryan\_T](https://forum.cabbageaudio.com/u/Bryan_T)\
**Post date:** [12 June 2024 13:28 UTC](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379/18 "2024-06-12T13:28:14Z")

</div>

The million-dollar question: are there any examples out there of creating/destroying instances of an instrument/effect dynamically? ChatGPT tried its best, but it was a mess.

Here’s the sort of thing ChatGPT ultimately produced:

```
<Cabbage>
form caption("Dynamic Delay Effect") size(600, 400), colour(200, 200, 200), pluginId("del1")

button bounds(10, 10, 150, 40) channel("createInstance") text("Create Instance", "Create Instance")
button bounds(170, 10, 150, 40) channel("destroyInstance") text("Destroy Instance", "Destroy Instance")

; Predefined controls for up to 4 instances
groupbox bounds(10, 60, 580, 100) text("Instance 1") identChannel("group1") visible(0)
hslider bounds(20, 80, 260, 40) channel("delayTime1") range(0.01, 1, 0.5, 0.01) text("Delay Time")
hslider bounds(300, 80, 260, 40) channel("feedback1") range(0, 1, 0.5, 0.01) text("Feedback")

groupbox bounds(10, 170, 580, 100) text("Instance 2") identChannel("group2") visible(0)
hslider bounds(20, 190, 260, 40) channel("delayTime2") range(0.01, 1, 0.5, 0.01) text("Delay Time")
hslider bounds(300, 190, 260, 40) channel("feedback2") range(0, 1, 0.5, 0.01) text("Feedback")

groupbox bounds(10, 280, 580, 100) text("Instance 3") identChannel("group3") visible(0)
hslider bounds(20, 300, 260, 40) channel("delayTime3") range(0.01, 1, 0.5, 0.01) text("Delay Time")
hslider bounds(300, 300, 260, 40) channel("feedback3") range(0, 1, 0.5, 0.01) text("Feedback")

groupbox bounds(10, 390, 580, 100) text("Instance 4") identChannel("group4") visible(0)
hslider bounds(20, 410, 260, 40) channel("delayTime4") range(0.01, 1, 0.5, 0.01) text("Delay Time")
hslider bounds(300, 410, 260, 40) channel("feedback4") range(0, 1, 0.5, 0.01) text("Feedback")

</Cabbage>

<CsoundSynthesizer>
<CsOptions>
-odac ; For Real-time audio out
</CsOptions>

<CsInstruments>

; Initialize the global variables
sr = 44100
ksmps = 32
nchnls = 2
0dbfs = 1

; Array to keep track of active instances
gkActiveInstances[] init 4
gkNumActiveInstances init 0

instr 1
    iInstance = p4
    SDelayTime sprintfk "delayTime%d", iInstance
    SFeedback sprintfk "feedback%d", iInstance

    kDelayTime chnget SDelayTime
    kFeedback chnget SFeedback

    aInL, aInR ins

    aDelL vdelay aInL, kDelayTime, 44100
    aDelR vdelay aInR, kDelayTime, 44100

    aOutL = aInL + (aDelL * kFeedback)
    aOutR = aInR + (aDelR * kFeedback)

    outs aOutL, aOutR
endin

instr 2
    iNumInstances init 4
    kTrigger chnget "createInstance"
    kDestroy chnget "destroyInstance"

    if (kTrigger == 1 && gkNumActiveInstances < iNumInstances) then
        gkActiveInstances[gkNumActiveInstances] = gkNumActiveInstances + 1
        event "i", 1, 0, -1, gkActiveInstances[gkNumActiveInstances]
        SGroup sprintfk "group%d", gkNumActiveInstances + 1
        chnset "visible(1)", SGroup
        gkNumActiveInstances += 1
    endif

    if (kDestroy == 1 && gkNumActiveInstances > 0) then
        gkNumActiveInstances -= 1
        SGroup sprintfk "group%d", gkNumActiveInstances + 1
        chnset "visible(0)", SGroup
        turnoff2 1, 1, gkActiveInstances[gkNumActiveInstances]
        gkActiveInstances[gkNumActiveInstances] = 0
    endif
endin

</CsInstruments>

<CsScore>
f 0 3600 ; Run for an hour
i 2 0 -1 ; Start the master instrument
</CsScore>

</CsoundSynthesizer>
```

---

<div class="post-metadata">

**Author:** ![ST\_Music](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/st_music/32/4405_2.png) [@ST\_Music](https://forum.cabbageaudio.com/u/ST_Music)\
**Post date:** [12 June 2024 23:48 UTC](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379/19 "2024-06-12T23:48:05Z")

</div>

There’s probably a few ways to approach this. Here’s a short example. The buttons here are not latched.

```
<Cabbage>
form caption("Dynamic Delay Effect") size(600, 400), colour(200, 200, 200), pluginId("del1")

button bounds(10, 10, 150, 40) channel("add") latched(0) text("Create Instance", "Create Instance")
button bounds(170, 10, 150, 40) channel("sub") latched(0) text("Destroy Instance", "Destroy Instance")
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-odac
</CsOptions>
<CsInstruments>

sr = 48000
ksmps = 32
nchnls = 1
0dbfs = 1

instr trig
; add instance
  kAdd chnget "add"
  kTrig trigger kAdd, .5, 0
; remove instance
  kSub chnget "sub"
  kStop trigger kSub, .5, 0

  kInstances init 0

  if kTrig == 1 && kInstances != 4 then
      event("i", "play", 0, 10^6)
      kInstances += 1
  endif
; printk2 kInstances
  if kStop == 1 then
; add release time to turnoff2
; to avoid clicks
      turnoff2("play", 2, 1)
      kInstances -= 1
  endif

endin

instr play
  iFreq = random:i(300, 500)
; add release time to envelope
; to avoid clicks
  aEnv = linsegr:a(1, p3, 1, 1, 0)
  aOut = poscil(.2, iFreq) * aEnv
  out(aOut)
endin 

</CsInstruments>
<CsScore>
i"trig" 0 z ; run indefinitely
</CsScore>
</CsoundSynthesizer>

```

Note turnoff2 has a release & there is a release envelope on the play instr set for the same length, to avoid clicks (fade out). Also turnoff2 will stop the most recently triggered instance, there are other options.

The != 4 may seem counterintuitive but this limits to 4 instances as the += is inside the if statement (see printk2 kInstances).

I noticed you only had one create & one destroy button so this concept should work fine(? works ok for me). If you were to get ambitious and have 4 seperate buttons (one to control each instance seperately) you’d probably want to consider a different approach, like using latched buttons and fractional instrument numbers or seperate instr for each delay.

---

<div class="post-metadata">

**Author:** ![Bryan\_T](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/bryan_t/32/5680_2.png) [@Bryan\_T](https://forum.cabbageaudio.com/u/Bryan_T)\
**Post date:** [5 July 2024 04:11 UTC](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379/20 "2024-07-05T04:11:46Z")

</div>

Here’s a new recording with the current version of my looping plugin. I have a long list of desired features that I’m slowly working through. I’m so excited, as I didn’t even know about Cabbage a month ago. All the guitar is through the looper in one pass. No effects other than a reverb in Logic.

https://w.soundcloud.com/player/?visual=false&url=https%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F1863525060&show_artwork=true&maxheight=166

[Next page](https://forum.cabbageaudio.com/t/new-to-cabbage-used-csound-ages-ago/4379.md?page=2)
