Cabbage Logo
Back to Cabbage Site

Stitching together two a-rate envelops

I’ve created a monophonic instrument that uses an a-rate envelope. It’s actually using two segments, one for the body of the envelope, and the second for the release. Everything works with the exception of the point when the note is released. I’m trying to get the second segment to start where the first left off (which could be any point of its stages). I can only imagine that this problem has been solved before, and if anyone could nudge me in the right direction, I would appreciate it… This code is currently how I am trying to do it…

gilvls[] fillarray 0, 1, .75, .25, .5, .3, .7, .4, 0
giPMPW_1_Rates[] fillarray .01, .1, 3, 4, 5, 1, .8, .8, 2

    if kReleased == 0 then
        aCarEnv linseg gilvls[0], girts[0], gilvls[1], girts[1], gilvls[2], girts[2], gilvls[3], girts[3], gilvls[4], girts[4], gilvls[5], girts[5], gilvls[6]
    else
        kCurr = downsamp(aCarEnv)
        aCarEnv linseg i(kCurr), girts[6], gilvls[7], girts[7], gilvls[8]
    endif

Should you not be using a linsegr for the release section?

instr 1

    a1 linseg 0, .1, 1, 1, 1

    if release() == 1 then
        a1 linsegr 1, .1, 1, 1, 0.001 
    endif

    a2 oscili a1, p4
    outs a2, a2

endin

I’m using Iain’s model for handling the midi controllers to make a monophonic instrument, and the release (the opcode) isn’t triggered as a result, because you have to wait for the last note to be released.

Right. I’ll have to have a look at how he does this…

http://iainmccurdy.org/CsoundRealtimeExamples/MIDI/BasicMonophonicSynth.csd

This is one of his mono instruments and he uses k-rate, he effectively does what I’m doing, but he doesn’t have to get an audio signal down to an i-rate variable. I might for now just use a k-rate, but I eventually would like to see how much a difference it would make to use an a-rate envelope. I’m doing a hybrid synth that acts like a traditional analogue synth, but still also offers dx style phase mod synthesis, and then it was gets pumped through a lowpass, resonant filter.

I think Iain’s more current approach to this is a lot simple is it not? And you don’t have to bother with stitching together segments of envelopes either?

Rory, just to let you know, I’ve made some progress on this with the help of the Csound List. I’ve included my most recent version, if you’re curious. I also got a response from the list that mentioned a plugin opcode that does this very thing, except I can’t seem to get those dylibs to load. I get a number of messages saying that some libraries aren’t loading. I guess this is a topic for another thread…

<Cabbage>
form caption("Untitled") size(400, 300), guiMode("queue"), pluginId("def1")
keyboard bounds(8, 158, 381, 95)
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d --midi-key-cps=4 --midi-velocity-amp=5
</CsOptions>
<CsInstruments>
; Initialize the global variables. 
ksmps = 32
nchnls = 2
0dbfs = 1

gkCPS init 0
gkAMP init 0

;instrument will be triggered by keyboard widget
instr 1
    ; trigger a new note only if this is the first of a group of notes that is played
    if active:i(p1) == 1 then
        event_i "i", 2, 0, -1
    endif
    ; read in note frequency and set global k-var to this. 
    ; gkCPS will always be determined by the most recent key played, but will return to the value of the previous note if the most recent key is released.
;    iCPS notnum
    iCPS cpsmidi
    iAMP ampmidi 1
    prints "iCPS %d %d\n", iCPS, active:i(p1)
    gkCPS init iCPS
    gkAMP init iAMP
endin

giLevels[] fillarray 0,  1, .75, .25, .5, .3, .7, .4, 0
giRates[] fillarray    .01,  .1,   3,  4,  5,  1, .8, 2

opcode TimeTrigger, k, i
    iTime xin
    kCounter init iTime
    kFlag init 0
;    if metro(4) == 1 then
;        printks "TimeTrigger kCounter: %f\n", 0, kCounter
;    endif
    if kCounter >= 0 then
        kCounter = kCounter - (1 / kr)
    else
        kFlag = 1
    endif
    xout kFlag
endop

instr 2
    iCount = 6
    iExtend = 0
    while iCount < 8 do
        iExtend = iExtend + (giRates[iCount] * 1.02)
        iCount = iCount + 1
    od
    kSet init 0
    kLastSampIndex = ksmps - 1
    kActive active 1
;    if metro(4) == 1 then
;        printk2 kActive
;    endif
    if kActive > 0 then
        aCarEnv linseg giLevels[0], giRates[0], giLevels[1], giRates[1], giLevels[2], giRates[2], giLevels[3], giRates[3], giLevels[4], giRates[4], giLevels[5], giRates[5], giLevels[6]
        kLastSample = aCarEnv[kLastSampIndex]
        ;printk2 kLastSample
    elseif kActive == 0 then
        if kSet == 0 then
            reinit setCurr
        endif
setCurr:
        iLast = i(kLastSample)
        kSet = 1
;        print iLast
        rireturn
        
        aCarEnv linseg iLast, giRates[6], giLevels[7], giRates[7], giLevels[8]
        if TimeTrigger(iExtend) == 1 then
            turnoff
        endif
    endif
    
    aOut vco2 gkAMP, gkCPS
    outs aOut * aCarEnv * gkAMP, aOut * aCarEnv * gkAMP
endin

</CsInstruments>
<CsScore>
;causes Csound to run for about 7000 years...
f0 z
</CsScore>
</CsoundSynthesizer>

Thanks for the update. Have you tried using the --opcode-lib CsOption to load those plugins?

Thanks, I didn’t realize that you had to add a commandline options. The docs I read only mentioned where to put them on the system. I’ve always gotten a list of warnings that mention plugins not loading, so I just thought you only needed to place them in the directory. The ones I’m adding now appear on this list.

I’ll check out the option tonight when I get home.

Hey, Rory. I tried to use the --opcode-lib option, but it doesn’t seem to make a difference. I’m wondering how much it has to do with the fact that I am using Apple hardware that they no longer want to support. I’m on 10.13.6, and I can’t install anything newer without some sort of “cheat” software. I want to move to Linux! I got a couple of older iMac’s that are staged to be reformatted!

I’m still using that versions of macOS and haven’t noticed any real issues with it? I think Eduardo can probably help on this given he wrote those plugins. Let us know how you resolve it :+1:

Cool! Are you getting any kind of warnings about plugins not loading?

Just the usual jack based plugins. But it’s not an issue for me. The reason I’m still on 10.13.6 is that I’ve never had any issues with it.

Do you have Homebrew installed? I tried about six months ago and it said my system was no longer supported. I’ve got two other iMacs, and I’ve been thinking about putting Linux on one of them!

I have Homebrew. I never had any issues with it.

Huh… Maybe I should try again. Thanks.